0

I have a comics website, and I'd like to keep track of how many people click like and dislike for a single comic id... I'd like to store the value in my database, and also report it back out to the browser.

This is my non-working solution:

viewcomic.php:

    <script type="text/javascript">
    function likeCounter(choice) {    
       var site = $("#site").val();
       var imgid = $("#imgid").val();
       $.get("./scripts/likecounter.php", {_choice : choice, _site : site, _id : imgid},
            function(returned_data) {
                $("#choice").html(returned_data);
            }
        );
}
</script>
       //Changed to try and work with buttons
   <button id="like" onClick="likeCounter(this.id)">Like</button>
   <button id="dislike" onClick="likeCounter(this.id)">Dislike</button>
   <input id="site" type="hidden" value="<?php echo $site; ?>">
   <input id="imgid" type="hidden" value="<?php echo $imgid; ?>">

<br />
Likes: <span id="choice"></span>

likecounter.php

<?php 
include 'dbconnect.php';

$site = $_GET['_site'];
$imgid = $_GET['_id'];
$input = $_GET['_choice'];

if ($site == "artwork") {
   $table = "comics";
}
else {
   $table = "artwork";
}

$likes = $mysqli->query("SELECT like FROM $table WHERE id = $imgid");
$dislikes = $mysqli->query("SELECT dislike FROM $table WHERE id = $imgid");


if ($input == "like") {
   $sql = "UPDATE $table SET like = like + 1 WHERE id = $imgid";
   $mysqli->query($sql);
   $likes++;

else if ($input == "dislike") {
   $sql = "UPDATE $table SET like = dislike + 1 WHERE id = $imgid";
   $mysqli->query($sql);
   $dislikes++;
}   
mysqli_close($mysqli);

echo "Likes: " . $likes . ", Dislikes: " . $dislikes;

?>

It's not incrementing the database value, and it's not reporting out a value to the browser. Any suggestions?

Thanks!

user3871
  • 12,432
  • 33
  • 128
  • 268
  • can you add, in the php a var_dump($_GET) please see what PHP is receiving. – Martin Lyne Nov 15 '12 at 23:57
  • 1
    When I see code like this I don't even know where to begin... I'd suggest you start by cleaning up you html, separate logic from markup, _use_ jQuery, indent your code properly, and maybe use JSON... – elclanrs Nov 15 '12 at 23:58
  • Your GET request seems to be a bit wrong... for starters I don't see 'id' being sent. – Shadow Nov 15 '12 at 23:59
  • 1
    My advice is to always start small, small units of work. get button click JS working, then make the ajax call work (as in, grab your homepage), then make the ajax call a flat page, then make that page display the values it receives.. and so on, slowly build the functionality, knowing you trust previous steps. Easier to debug too. – Martin Lyne Nov 16 '12 at 00:04
  • you are also not realy sending the site ... also in SQL i try to avoid using words such as "like" as field or table names it is bad practice – Eyal Alsheich Nov 16 '12 at 00:04
  • What Eyal means is that "like" is often a reserved word in DB-land, so bad things can happen :) – Martin Lyne Nov 16 '12 at 00:06
  • @MartinLyne Thanks, I changed them to like_count, and dislike_count. I think I will use a button instead, like you suggested – user3871 Nov 16 '12 at 00:07
  • @MartinLyne I'm trying buttons, but that doesn't seem to work either – user3871 Nov 16 '12 at 00:13
  • Buttons? I'm not suer what difference that would make. – Martin Lyne Nov 16 '12 at 00:15
  • @MartinLyne is it possible to assign a php variable a single value from a database field? Ex. $likes = $mysqli->query("SELECT like_count FROM $table WHERE id = $imdid"); ?? – user3871 Nov 16 '12 at 00:29

3 Answers3

1

I think

$site = $_GET['site'];`

Should be

$site = $_GET['_site'];` 

You are also not sending the id- $imgid = $_GET['id'];

Please look into PDO or MySQLi as your code is unsafe (look up SQL injection).

Kurt
  • 7,102
  • 2
  • 19
  • 16
1

I believe you will need to change the column name "like" to something else as that word is reserved in SQL here is a list of reserved words

just change it to "likes" or something like that.

another minor thing is that you can get both values in a single query

Select likes,dislikes from $table where id = $ImgID
Eyal Alsheich
  • 452
  • 4
  • 12
  • Thanks! Is it possible to assign a php variable = single value from a database field? Ex: $likes = $mysqli->query("SELECT like_count FROM $table WHERE id = $imgid"); – user3871 Nov 16 '12 at 00:34
  • the select query return an array, you can use mysql_fetch_assoc() function to recieve an associative array from the database and then the values are easily accesed from there – Eyal Alsheich Nov 16 '12 at 02:29
1

The technical problem is this line:

$.get("./scripts/likecounter.php", {_choice : choice, _site : site, _id : id}...

as site and id are undefined you'll be getting a javascript error ReferenceError: site is not defined

Try:

$.get("./scripts/likecounter.php", {_choice : choice, _site : "<?php echo $site; ?>", _id : "<?php echo $imgid; ?>"}...

You don't need the hidden inputs, also onClick should be onclick.

Other quick suggestions:

Make sure $imgid is actually an integer:

$imgid = intval($_GET['_id']);
if($imgid == 0) exit('Invalid id');

The following doesn't need to be separate:

$likes = $mysqli->query("SELECT like FROM $table WHERE id = $imgid");
$dislikes = $mysqli->query("SELECT dislike FROM $table WHERE id = $imgid");

$result = $mysqli->query("SELECT like_count, dislike_count FROM $table WHERE id = $imgid");

$mysqli->query will only return a mysqli_result, meaning you can't just echo it out, you'll have to do a fetch, and because you know you are only getting a single result you can just use list($likes, $dislikes) = $result->fetch_array(MYSQLI_NUM);

Have a read of the docs to help you understand what the heck I'm going on about.

As you mentioned people can just keep hitting like/dislike all they want, you'll need to limit this with an IP log of some sort. For example setup a new database table with the following fields; ip, table, imgid. Then when someone "likes" log their IP:

$sql = "INSERT INTO xxx (ip, table_name, imgid) VALUES(\"".$_SERVER['REMOTE_ADDR']."\", \"$table\", $imgid)";
$mysqli->query($sql);

Then check if they have a record before adding a new like:

$sql = "SELECT ip FROM xxx WHERE ip = \"".$_SERVER['REMOTE_ADDR']."\" AND table_name = "$table" AND imgid = $imgid";
$result = $mysqli->query($sql);
if($result->num_rows == 0) { ...if($input ==... }
PieSub
  • 318
  • 1
  • 8
  • Thank you so much man! You were incredibly helpful. It works perfectly now! Is there a way I can do these as links instead of buttons? (So I can design a custom like and dislike "button"). Also, how can I keep the counter always visible, and not just visible when the result is returned to ""? – user3871 Nov 16 '12 at 00:44
  • 1
    You can do them as links no problems, doesn't make a difference. To show the current likes/dislikes just do the same database query in your viewcomic.php script and then use: `Likes: Dislikes ` – PieSub Nov 16 '12 at 00:53
  • Can you explain "do the same database query in your viewcomic.php" Please? – user3871 Nov 16 '12 at 01:20
  • Actually, I just realized... a single user can just keep pressing "like". How can I limit one like per user? – user3871 Nov 16 '12 at 01:21
  • 1
    When I say "do the same database query" I mean just copy `$result = $mysqli->query("SELECT like_count, dislike_count`...(and the rest) into the other script so you have access to $likes and $dislikes. – PieSub Nov 16 '12 at 02:04
  • I'm implementing your suggestion, but it's giving me an error at "if ($result->num_rows == 0) { ", stating "Trying to get property of a non-object". Any ideas? – user3871 Nov 23 '12 at 23:29
  • You probably have a MySQL error, change `$result = $mysqli->query($sql);` to `if($result = $mysqli->query($sql)) { if($result->num_rows... } else { printf("Error: %s\n", $mysqli->error); }` – PieSub Nov 24 '12 at 03:27
  • I've redone the code and posted here earlier- mind checking out the new issues and helping me out some more? http://stackoverflow.com/questions/13537239/php-like-dislike-counter – user3871 Nov 24 '12 at 03:38