-1

I have used someone else's code that uses the ipaddress way. However, I would like to use a code that checks for the current userid and the id number.

$ipaddress = md5($_SERVER['REMOTE_ADDR']); // here I am taking IP as UniqueID but you can have user_id from Database or SESSION

/* Database connection settings */
$con = mysqli_connect('localhost','root','','database');

if (mysqli_connect_errno()) {
    echo "<p>Connection failed:".mysqli_connect_error()."</p>\n";
}   /* end of the connection */

if (isset($_POST['rate']) && !empty($_POST['rate'])) {
    $rate =  mysqli_real_escape_string($con, $_POST['rate']);
    // check if user has already rated
    $sql = "SELECT `id` FROM `tbl_rating` WHERE `user_id`='" . $ipaddress . "'";
    $result = mysqli_query( $con, $sql);
    $row =  mysqli_fetch_assoc();//$result->fetch_assoc();
    if (mysqli_num_rows($result) > 0) {
        //$result->num_rows > 0) {
        echo $row['id'];
    } else {
        $sql = "INSERT INTO `tbl_rating` ( `rate`, `user_id`) VALUES ('" . $rate . "', '" . $ipaddress . "'); ";
        if (mysqli_query($con, $sql)) {
            echo "0";
        }
    }
}
//$conn->close();
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Amir HD
  • 21
  • 2
  • So, what is the problem you are seeing in trying that? – Sloan Thrasher Apr 04 '17 at 23:03
  • I am not sure on how to do it? I'm new to php... – Amir HD Apr 04 '17 at 23:06
  • I'd appreciate a help from someone as I need this for my final year project – Amir HD Apr 04 '17 at 23:13
  • You first have to define how you are going to identify the user, if you are not going to use the IP address. Remember that session cookies can, and will, be deleted, so that's not the way to go. You have a login system? – KIKO Software Apr 04 '17 at 23:14
  • Yes I do have a login system and it works perfectly fine – Amir HD Apr 04 '17 at 23:16
  • Pass $result into mysqli_fetch_assoc() function `$row = mysqli_fetch_assoc($result);` – Yolo Apr 04 '17 at 23:17
  • Well, require users to log in, before they can rate. Then you can indeed use the user id to track how many times, and when, users rated. – KIKO Software Apr 04 '17 at 23:18
  • How would i link the login system to the rating system? This was my second question to be honest? – Amir HD Apr 04 '17 at 23:23
  • Hire a programmer, they can help you fix some issue, design a new feature or full website. There are many freelancing website where you can find one. And there are some cheap options as well. Good Luck – Abdul Rehman Apr 06 '17 at 05:56
  • 1
    just a small FYI, your `$conn->close();` has too many `n`'s in it. if you are going to uncomment the close, use: `$con->close();` – mickmackusa Apr 06 '17 at 05:56
  • [Little Bobby](http://bobby-tables.com/) says ***[your script is at risk for SQL Injection Attacks.](http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php)*** Learn about [prepared](http://en.wikipedia.org/wiki/Prepared_statement) statements for [MySQLi](http://php.net/manual/en/mysqli.quickstart.prepared-statements.php). Even [escaping the string](http://stackoverflow.com/questions/5741187/sql-injection-that-gets-around-mysql-real-escape-string) is not safe! – Jay Blanchard Apr 13 '17 at 11:49

1 Answers1

5

In your database table, set the user_id column as UNIQUE KEY. That way, if a user tries to cast a second vote, then the database will deny the INSERT query and you can just display a message when affected rows = 0.

Alternatively, (and better from a UX perspective) you can preemptively do a SELECT query for the logged in user before loading the page content:

$allow_rating = "false";  // default value

if (!$conn = new mysqli("localhost", "root","","database")) {
    echo "Database Connection Error: " , $conn->connect_error;  // never show to public
} elseif (!$stmt = $conn->prepare("SELECT rate FROM tbl_rating WHERE user_id=? LIMIT 1")) {
    echo "Prepare Syntax Error: " , $conn->error;  // never show to public
} else { 
    if (!$stmt->bind_param("s", $ipaddress) || !$stmt->execute() || !$stmt->store_result()) {
        echo "Statement Error: " , $stmt->error;  // never show to public
    } elseif (!$stmt->num_rows) {
        $allow_rating = "true";  // only when everything works and user hasn't voted yet
    }
    $stmt->close();
}

echo "Rating Permission: $allow_rating";

And if they already have a row in the table, then don't even give them the chance to submit again.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
  • 2
    Yeah. That's should work properly. But I would recommend to add a new table, containing user_id, post_id (or any_id), and a boolean field of true or false. By that, if the same user tries to rate again, you will query if it's id exist in this new table and if value is true in the boolean field, display a message telling him that he can't rate. If you want to use an IP address, it is okay, but sometimes he would change his place, his network, his phone, and the ip would change too. And you should consider that too. And the cookies is not a great solution. Just use the IP address and extra table – alim1990 Apr 06 '17 at 05:54
  • 1
    And for extra level of security I would like to recommend re-write the script with PDO. MySQLi is good enough, but I would prefer PDO instead. – alim1990 Apr 06 '17 at 06:01
  • @AmirHD I've updated my answer to include some conditional checkpoints for easier debugging. Is there anything else that you'd like me to adjust or explain? or is this an acceptable answer? – mickmackusa Jun 27 '18 at 01:10