Like button just keeps counting

Ok, so I have a database with 1 table and 4 collumns: id, likes, dislikes, voted.

And a script that should count the likes or dislikes, but only once per click, wich it does, but if I click the like button or dislike button too many times before the page has time to refresh it counts all those clicks.

Need to mention that buttons disappear after click and result is shown up.
So what is the problem with this?
Here’s the script:

php

<?php session_start(); include"inc.php"; $query = mysql_query("SELECT * FROM votes"); $row = mysql_fetch_array($query); $id = $row['id']; $likes = $row['likes']; $dislikes = $row['dislikes']; $voted = $row['voted']; if(isset($_POST['like'])){ $likes1 = $likes+1; mysql_query("UPDATE votes SET likes='$likes1'"); mysql_query("UPDATE votes SET voted='1'"); header("Location: index.php"); } if (isset($_POST['dislike'])){ $dislikes1 = $dislikes+1; header("Location: index.php"); mysql_query("UPDATE votes SET dislikes='$dislikes1'"); } if($voted == "1"){ echo "Likes: $likes
Dislikes: $dislikes
"; }else{ echo" "; } ?>

php

Thanks.

There are a couple of different solutions that you could implement. One uses javascript and is pretty simple (but will not work if the user has javascript disabled), anything else is more complicated.

The javascript solution involves adding the following script to your page:<script type="text/javascript"> function disableSubmits(form) { myForm.like.disabled = true; myForm.dislike.disabled = true; return true; }

You will then modify your form like this:echo "<form action='' name='myForm' method='POST' onsubmit='return disableSubmits(this.form)'>

This should disable the buttons as soon as one is pushed.

Another possibility is to use a session variable to only allow 1 click per session. You would need to setup another table to monitor the sessions and check for a used session prior to processing the click. This has the advantage of not being dependent on the user allowing javascript, but could be a little harder to implement.

Ok thanks. So how do i do that?

Oh wait!
How do i insert javascript in php?

Javascript is inserted between

I thought I posted this earlier, but apparently it didn’t go through…

I wanted to put together a complete example for you. I am glad I did, as it turned out that the two submit buttons created a bigger wrinkle than I had originally realized.

One issue that I hadn’t considered is that once the buttons are disabled, they no longer are included in the post. This means that I was on the right track, but unfortunately my original suggestion was lacking some critical components. I apologize for this.

Below you should find a full working example of how to implement a javascript solution, based on my previous post. When javascript is enabled on the client’s browser, the buttons will be immediately disabled upon clicking on one and they will re-enable after the post is completed.

There are a few caveats to doing this, as you will see.

First, you will need to create an extra input with a type = hidden.
Second, depending on whether javascript is enabled, your post will either include a variable “sub” with the value of the clicked button, or the actual button name and value when javascript is disabled.

Since the example posts extremely fast on my server, I cannot actually see the buttons being disabled. To demonstrate that it does work, you can set the return value in the script to false. This will prevent the form from posting, but you will see that the buttons are being disabled when javascript is enabled in the browser.

Again, I apologize for my prior oversight and hope that this example is of use. Should you decide that this is not the approach you wish to take, I would be happy to try to help you come up with a more server sided solution. The benefit of the method I illustrate is that it is very efficient and relatively easy to implement. The downside to it is that not everyone will have javascript enabled.

Please let me know if you have any questions, or if this test script doesn’t work as intended.

jay[php]

POST Button Disable Demonstratrion <?php if(!empty($_POST['sub'])) $choice = $_POST['sub']; elseif(!empty($_POST['like'])) $choice = 'Like'; elseif(!empty($_POST['dislike'])) $choice = 'Dislike'; if($choice=='Like') echo 'You like me! You really like me!'; if($choice=='Dislike') echo 'What did I ever do to you?'; ?> [/php]

First of all thank you.
I tested the script but for some reason the “You like me! You really like me!” or “What did I ever do to you?” never show up. I can see that the buttons are being disabled but then they are clickable again.

I’m sorry I didn’t mention that i wanted to allow the user to click only once on those buttons and then the result of how many likes dislikes would be shown instead of buttons(the buttons would then disappear).

Oh and also javascript enabled or not is not a big problem with this since my page actually requires javascript to be enabled in order for the viewer to understand anything of it, so don’t worry about that.

OK I started a new script from scratch and I’m checking to see if IP address exists in database. If it doesn’t then it is added, if it does exists then the script just says it does.
All good so far only that every time I refresh the page the address is added nontheless, even if it exits and even if the script says it does. What am I doing wrong? Please help.

[php]<?php
$address=$_SERVER[‘REMOTE_ADDR’];

$con = mysql_connect(“localhost”,“username”,“password”);
if (!$con)
{
die(‘Could not connect: ’ . mysql_error());
}
mysql_select_db(“my_db”, $con);
$result = mysql_query(“SELECT * FROM votes”);
while($row = mysql_fetch_array($result))
{
if ($row[‘address’]==$address)
{
echo “exists”;
}
else
{
$sql="INSERT INTO votes (address) VALUES (’$address’)";
if (!mysql_query($sql,$con))
{
die('Error: ’ . mysql_error());
}
else echo"address added";
}
}

mysql_close($con);
?>[/php]

There is a much easier way to do what you want:

Setup a unique key on your address column of your votes database. Then try the following code:[php]<?php
if(!empty($_SERVER[‘HTTP_CLIENT_IP’])) $ip=$_SERVER[‘HTTP_CLIENT_IP’];
elseif(!empty($_SERVER[‘HTTP_X_FORWARDED_FOR’])) $ip=$_SERVER[‘HTTP_X_FORWARDED_FOR’];
else $ip=$_SERVER[‘REMOTE_ADDR’];

$result = mysql_query(“INSERT INTO votes (address) VALUES (’$ip’)”);
if(!$result)
{
$error = mysql_errno();
if($error == 1062) die(‘You can only vote once.’);
}
mysql_close($con);
?>[/php]

Note: Getting the user’s real IP address can be a lot more challenging than most people realize. Many users are behind a proxy; many of which will completely hide the user’s IP. The $_SERVER[‘REMOTE_ADDR’] is not usually the best way, but it makes a good fallback if other environmental variables are not present. I have included two other tests in the code above. There are several more, but these three (in this order) are generally going to cover most of the scenarios where a person isn’t hiding their IP. For your application, I believe this will work fine.

To explain the code a little: By setting a unique key on your address column, you are telling the server to only allow successful insertions when the address isn’t already present. This means that instead of having to first check if the address exists, it will fail (the address will not be added) and return an error number 1062 (Duplicate Entry For Key). The code checks for this error and dies with a notice that you can only vote once. The entire if(!$result) section is optional and is there only to provide some feedback. It could be omitted or changed freely.

Please let me know if you have any questions or if this doesn’t work as expected.

Best,

jay

Thanks, that works fine, didn’t know about the unique key.
If I can ask you something else though, how can I use a button in a html file to run the php file on click.
I looked it up but I can’t find anything about this.

I have this form:

<form action='vote.php' method='POST'><input type='submit' name='like' value='Like'></form>;

in html, but if I click on the button it will change page to the php file. I want the output of that file to be shown in html (like: “You can only vote once.” in the code above to appear in my index page where everything else is).

There is no truly good way to do what you want, but there are some options.

First, pages that have the .html extension will not run php. There is a way to force all of your html files to be parsed by php by modifying your .htaccess file, but it is generally considered a last resort option and many will strongly advise against it. Make sure you backup your original .htaccess file before attempting to edit it!

A second option is an html iframe element. An iframe will allow you to place a php page inside your html page. You can adjust the setting so that it is visually undetectable.

A third option is to use a php generated image on your html page. This could get a bit tricky, but what you would do is setup an html image tag with a src pointing to a php file. The php file would then get the ip address and see if it is already in the database. If it is, it would return an image (or a generated text image) stating “You have already voted” or “Please vote now”. Or something like that. If you have never used php’s GD library, this will have a steeper learning curve as compared to the iframe option. On the bright side, you will learn a little about generating and manipulating graphics in php.

Off the top of my head, these three options seem the best. Perhaps somebody else will have a better idea - I’ll think about it a little more and let you know if I come up with anything else.

Let me know if you would like more information about any of these options.

jay

Thanks for everything. I’ll look into thesse options myself.
I’ll leave the topic open for awhile of u say you’ll think about it a little more.
Thanks again.
Never thought it would be so hard to make a simple like/dislike button. ::slight_smile:

George,

I think I have a good solution for you. Are you still working on this?

it might work using jquery and $(document).ready() to avoid those extra counts before the page has loaded… did you solve this?

I’ve used this:

$(document).ready(function(){ $("button").click(); });
and buttons are unclickable while the page loads, but I can’t really test this because I have a php file that runs on load and checks if user ip is in database. If it is, the results will be displayed instead of buttons, and if not, I wanted to do nothing, but the buttons are removed entirely. The file looks like this:
[php]<?php
if(!empty($_SERVER[‘HTTP_CLIENT_IP’]))
$ip=$_SERVER[‘HTTP_CLIENT_IP’];
elseif(!empty($_SERVER[‘HTTP_X_FORWARDED_FOR’]))
$ip=$_SERVER[‘HTTP_X_FORWARDED_FOR’];
else $ip=$_SERVER[‘REMOTE_ADDR’];

$con = mysql_connect(“localhost”,“pylon_pylon”,“SeeKerless123”);
if (!$con)
{
die('Could not connect: ’ . mysql_error());
}
mysql_select_db(“pylon_db”, $con);

$table = mysql_query(“SELECT * FROM votes”);
while($row = mysql_fetch_array($table)) {
if($row[‘address’] == $ip)
{$response = “Display results.”;
echo $response;
}}
?>[/php]
and I’m using " xmlhttp.responseText " in the index in the function that calls the php file.
Is there a way to make the buttons stay on the page if user ip is not in database?

Oh, and here’s the full function in index.html:

function check() { var xmlhttp; if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp=new XMLHttpRequest(); } else {// code for IE6, IE5 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4 && xmlhttp.status==200) { document.getElementById("vote").innerHTML=xmlhttp.responseText; } } xmlhttp.open("POST","check.php",true); xmlhttp.send(); }

I think the solution is in yhe javascript function check() in my html file, but I dont know how to call the ‘response’ variable from the php file and check it in the function like so:

if (response == value)
{document.getElementById(“vote”).innerHTML=xmlhttp.responseText;}
else{do nothing or ignore this function or something}

but I don’t know how to do that.

Man, php is getting so frustrating, what’s the use of gazzillion languages to make one webpage. It makes no sense.

Sponsor our Newsletter | Privacy Policy | Terms of Service