Create Unique Poll/Vote/Survey in PHP

Create unique Poll/vote/survey in php

To restrict the number of votes per person, you need to track the person.

Now there can be several ways to do that, and I'll list them with their pros and cons. Its for you to decide which method suits you best.

  1. login: this will offer you ultimate control. But its also a little cumbersome for the user. and its your last preference
  2. IP: how will you handle people behind web proxies? How about people with dialup connections and/or dynamic IPs?
  3. cookies: this is good for short term polls, so you can set the expiration of cookies to a time when the poll has ended. But, a potential drawback is that a user (contrasted with a luser) will know how to delete the cookies!
  4. openId: While this method is not too different from the 'login' method, this saves the user from registration (which really is the part that sux the most about logins).

EDIT: the problem with this situation is that you need to resolve the identity of the user. I think OpenID does this pretty darn well.

Cheers,

jrh.

What is a good free online poll/survey app?

http://docs.google.com Create a form and collect results of the survey in spreadsheet

validating a poll for user to vote once

It's no 100% solution, but you can use a browser fingerprint in combination with the IP adress. See this site for some usable and easily gettable browser properties.

Disadvantages: Some people may be left out (especially in large organizations with a very restrictive and thus homogeneous infrastructure), others may vote twice, for example by using different browsers.

If you want a 95% solution you have to require people to sign up with their email adress and proving that they received the email by klicking an embedded link, but depending on how much interest they take in voting, it may scare off a lot of potential voters.

A 100% solution for this problem does not exist, as far as I'm aware of.

Edit: Cookies are another obvious choice if you don't care too much about people gaming the poll system (just writing an auto-voter that ignores the cookies you send it).

Preventing multiple voting in a survey

in order to prevent people from entering multiple answers, you want to use sessions (this implies that you have to put that page behind a login). Alternatively, you can use the IP.

However, the IP changes. This implies that, even if you use the IP only and store it somewhere (possibly encrypted), so that whoever has used that IP won't be able to answer again, you won't prevent me from answering again.

Have you considered enabling login with social networks, such as facbook and twitter or google+? It's an alternative to login.

If you're happy with the IP only, you can simply create a database table with IP entries. Let's say you have it already and that the table has three columns (id, ip, survey).

    <?
//take the ip
$user = $_SERVER['REMOTE_ADDR'];

//sanitize the ip (is it valid?). This can probably skipped with prepared statements but one never knows

if (filter_var($user, FILTER_VALIDATE_IP)) {
echo "This (ip_a) IP address is considered valid."; //for debug
$user = md5( $user); //or whatever else if not md5

$query = $mysqli->prepare("insert into iptable values (NULL, ?, ?)");
//etc.

}else{
//return error
}
?>

I hope this helps. I'd prefer a login though.

Unique IPs in a voting system

The Unobtainably-Perfect: (Unique Govt Number)

  • User votes using a verifiable unique identifier like a social-security or passport number

The Close-Enough-For-Reality: (Email/3rd Party Auth)

  • user registers an account with an email address and password (or google/facebook)
  • 1 email address = 1 vote
  • Users can't clear cookies and get extra votes, App doesn't shut 1000's out with shared IPs

The Good-Thought-But-False-Pretense (IP addresses)

  • Office buildings: 1000's of users on the same external IP get shut-out
  • Universites: Connect to wireless in classroom. Vote. Move to next classroom. Reconnect and vote again

The Crash-And-Burn (Cookies)

  1. Vote
  2. ctrl shft del enter
  3. vote
  4. repeat

PHP/MYSQL only allowing one vote per member?

Here's a quick and dirty approach:

$sql_query = "SELECT FROM awards_2009_votes WHERE member_id = '$memberid'";
$sql_result = mysql_query($sql_query);
$num_rows = mysql_num_rows($sql_result);

if ($num_rows > 0) {
// this member has already voted
} else {
// carry on
}

As Piskvor pointed out, though, this solution has (at least) two limitations:

  1. It is confined to the method containing it, so it is not preventing multiple votes in general -- only through this particular method. (You could write a function to contain this same check, but you'd still have to call that function everywhere a user tries to vote.)
  2. It results in additional strain on the database, which may be unacceptable in a high-traffic scenario.

With these points in mind, my recommendation would be to first run a script to check for any occurrence of duplicate member_id values in your votes table, remove all but one in each case, and THEN add the UNIQUE constraint to your table. From there you can be sure your table will never have more than one row with the same member_id.

Code for Poll with unique voters

you can try this.

<script>
function setCookie(cname,cvalue,exdays)
{
var d = new Date();
d.setTime(d.getTime()+(exdays*24*60*60*1000));
var expires = "expires="+d.toGMTString();
document.cookie = cname + "=" + cvalue + "; " + expires;
}

function getCookie(cname)
{
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i=0; i<ca.length; i++)
{
var c = ca[i].trim();
if (c.indexOf(name)==0) return c.substring(name.length,c.length);
}
return "";
}

function getVote(int) {
if (window.XMLHttpRequest) {
xmlhttp=new XMLHttpRequest();
} else {
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
setCookie("voted",1,1)
document.getElementById("poll").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","poll_vote.php?vote="+int,true);
if(!getCookie("voted")){
xmlhttp.send();
}
else{
alert("you already voted!")
}
}
</script>

there is a second variant is storing a voted IP in a DB or file.

How to make sure users can only vote once per post

I would create a separate table called user_post that would have the user_id and post_id - in fact, you can make those columns a multi-column primary key.

When a user votes on a post, you can use the following query:

REPLACE INTO user_post (user_id, post_id, vote) VALUES (:userId, :postId, :vote)

Replace is essentially saying 'insert unless there is a unique key conflict, if so, update the row'. Or, you can use:

INSERT IGNORE INTO user_post (user_id, post_id, vote) VALUES (:userId, :postId, :vote)

which essentially says 'insert unless there is a unique key conflict, if so, ignore' (if you only want to keep the first vote).



Related Topics



Leave a reply



Submit