使用PHP和AJAX进行Upvote和Downvote

时间:2017-08-19 11:27:08

标签: php jquery mysql ajax

我正在尝试实施upvote / downvote系统。用户点击upvote或downvote按钮,触发AJAX代码,在数据库中插入或更新投票。

这会在点击时触发AJAX请求。

    echo '<i id="'.$row['postID'].'" class="fa fa-chevron-up vote_up" aria-hidden="true"></i>';
    echo '<i id="'.$row['postID'].'" class="fa fa-chevron-down vote_down" aria-hidden="true"></i>';

这是ajax代码 -

$(document).ready(function () {
    $("i.vote_up").click(function () {
        the_id = $(this).attr('id');
        $.ajax({
            type: "POST",
            data: "action=upvote&id=" + $(this).attr("id"),
            url: "vote.php",
            success: function (msg) {
                alert("Success");
            },
            error: function () {
                alert("Error");
            }
        });
    });
});

$(document).ready(function () {
    $("i.vote_down").click(function () {
        the_id = $(this).attr('id');
        $.ajax({
            type: "POST",
            data: "action=downvote&id=" + $(this).attr("id"),
            url: "vote.php",
            success: function (msg) {
                alert("Success");
            },
            error: function () {
                alert("Error");
            }
        });
    });
}); 

这是处理投票的代码。

<?php
require('includes/config.php');
$action   = $_POST['action'];
$postID   = $_POST['id'];
$memberID = $_SESSION['memberID'];
switch ($action) {
    case "upvote":
        try {
            $stmt = $db->prepare('SELECT memberID,postID,voteType FROM votes WHERE postID = :postID AND memberID =:memberID');
            $stmt->execute(array(
                ':postID' => $postID,
                ':memberID' => $memberID
            ));
            $row = $stmt->fetch();
            if ($row['voteType'] == "up") {
                $stmt = $db->prepare('DELETE FROM votes WHERE postID = :postID AND memberID =:memberID');
                $stmt->execute(array(
                    ':postID' => $postID,
                    ':memberID' => $memberID
                ));
                $stmt = $db->prepare('UPDATE posts SET upVote = upVote -1 WHERE postID = :postID');
                $stmt->execute(array(
                    ':postID' => $postID
                ));
            }

            else if ($row['voteType'] == "down") {
                $voteType = "up";
                $stmt     = $db->prepare('UPDATE votes SET voteType = :voteType WHERE postID = :postID AND memberID =:memberID');
                $stmt->execute(array(
                    ':voteType' => $voteType,
                    ':postID' => $postID,
                    ':memberID' => $memberID
                ));
                $stmt = $db->prepare('UPDATE posts SET upVote = upVote +1, downVote = downVote -1 WHERE postID = :postID');
                $stmt->execute(array(
                    ':postID' => $postID
                ));
            } else if ($row['memberID'] == null) {
                $voteType = "up";
                $stmt     = $db->prepare('INSERT INTO votes (postID,memberID,voteType) VALUES (:postID, :memberID, :voteType)');
                $stmt->execute(array(
                    ':postID' => $postID,
                    ':memberID' => $memberID,
                    ':voteType' => $voteType
                ));
                $stmt = $db->prepare('UPDATE posts SET upVote = upVote +1 WHERE postID = :postID');
                $stmt->execute(array(
                    ':postID' => $postID
                ));
            }
        }
        catch (PDOException $e) {
            echo $e->getMessage();
        }
        break;
    case "downvote":
        try {
            $stmt = $db->prepare('SELECT memberID,postID,voteType FROM votes WHERE postID = :postID AND memberID =:memberID');
            $stmt->execute(array(
                ':postID' => $postID,
                ':memberID' => $memberID
            ));
            $row = $stmt->fetch();
            if ($row['voteType'] == "down") {
                $stmt = $db->prepare('DELETE FROM votes WHERE postID = :postID AND memberID =:memberID');
                $stmt->execute(array(
                    ':postID' => $postID,
                    ':memberID' => $memberID
                ));
                $stmt = $db->prepare('UPDATE posts SET downVote = downVote -1 WHERE postID = :postID');
                $stmt->execute(array(
                    ':postID' => $postID
                ));
            } else if ($row['voteType'] == "up") {
                $voteType = "down";
                $stmt     = $db->prepare('UPDATE votes SET voteType = :voteType WHERE postID = :postID AND memberID =:memberID');
                $stmt->execute(array(
                    ':voteType' => $voteType,
                    ':postID' => $postID,
                    ':memberID' => $memberID
                ));
                $stmt = $db->prepare('UPDATE posts SET downVote = downVote +1, upVote = upVote -1 WHERE postID = :postID');
                $stmt->execute(array(
                    ':postID' => $postID
                ));
            } else if ($row['memberID'] == null) {
                $voteType = "down";
                $stmt     = $db->prepare('INSERT INTO votes (postID,memberID,voteType) VALUES (:postID, :memberID, :voteType)');
                $stmt->execute(array(
                    ':postID' => $postID,
                    ':memberID' => $memberID,
                    ':voteType' => $voteType
                ));
                $stmt = $db->prepare('UPDATE posts SET downVote = downVote +1 WHERE postID = :postID');
                $stmt->execute(array(
                    ':postID' => $postID
                ));
            }
        }
        catch (PDOException $e) {
            echo $e->getMessage();
        }
        break;
}
?> 

这一切都运转良好,但我想知道是否有其他方法可以做到这一点?还有如何在网站上使用此代码安全?

1 个答案:

答案 0 :(得分:0)

如果您希望它更安全,则应在将参数添加到数据库之前绑定参数

$stmt = $db->prepare('UPDATE posts SET downVote = downVote -1 WHERE postID = :postID');
$stmt->execute(array(':postID' => $postID));

将成为:

$stmt = $db->prepare('UPDATE posts SET downVote = downVote -1 WHERE postID = :postID');
$stmt->bindParam(":postID", $postID, 1); //1 is the datatype for Int; 2: for String; 0 for Bool
$stmt->execute();

http://php.net/manual/en/pdostatement.bindparam.php

当您从“POST”

获取该值时,检查该值是否存在也是一件好事
$postID   = $_POST['id'];

可能会成为

(isset($_POST['id'])) ? $postID = $_POST['id'] : $postID = 0

我建议你做的另一件事就是在你的ajax请求中隐藏你的页面名称。

url: "vote.php",

在.htaccess中使用RewriteRule来隐藏网址的名称,然后在你的ajax请求中它会变成类似

的内容
url: "request-vote"

https://mediatemple.net/community/products/dv/204643270/using-htaccess-rewrite-rules

+++更新 - 回复@Mahim Parsai +++

首先更新你的ajax请求,你需要返回一些值。 在您的代码中,您正在更新数据库,但没有返回任何内容。

首先我将创建一个变量来保存你的downVote和upVote,我还将创建一个变量来保存你的ajax请求的结果。

$downVote = 0; //will hold the result from the database
$upVote = 0; //will hold the result from the database
$ajax_response=[]; //set an empty array where we will store our result for the ajax request

我举例说明如何从数据库中获取downVote的值并将其发送到您的ajax请求

//get the value from the database
$stmt = $db->prepare('SELECT downVote FROM posts WHERE postID=:postID');
$stmt->bindParam(':postId', $postID, 1);
$stmt->execute();
$row = $stmt->fetch(5); //fetch the result from your request, (5) means I want to get an object as return
$downVote = $row->downVote; // store the value to the variable set at the beginning, downVote is the name of the column in your table, here we accessing the object

在“catch”的“}”之前,将值添加到ajax响应的数组中

$ajax_response['downVote'] = $downVote;

//也让你的脚本知道我们成功了这个downVote,所以让我们把它添加到数组

$ajax_response['status'] = "success";

所以在你的catch方法中添加这个

$ajax_response['status'] = "error";

如果您还想跟踪ajax请求中的错误,请在catch方法中添加

$ajax_response['error'] = $e->getMessage();

在脚本结束时将数组发送到您的ajax请求。 您需要将结果编码为json以便由ajax

读取
echo json_encode($ajax_response);

不要忘记关闭你的mysql连接

$db=null;

现在你可以从你的ajax请求中做到

success: function (msg) {
  if(msg.status=="success"){
     //we succeed
    var downVote = msg.downVote //the result from the database
  }
  else{
  //we return error
    alert(msg.error);
  }
},
error: function () {
  alert(msg.error);
}