使用PHP和AJAX的向上投票和向下投票

使用PHP和AJAX的向上投票和向下投票,php,jquery,mysql,ajax,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-c

我正在尝试实现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>';
这是处理投票的代码

<?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;
}
?> 


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

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

$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();

另外,当您从“POST”获取该值时,最好检查该值是否存在

可能成为

(isset($_POST['id'])) ? $postID = $_POST['id'] : $postID = 0
我还可以建议您在ajax请求中隐藏页面名称

url: "vote.php",
$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
在.htaccess中使用RewriteRule来隐藏url的名称,然后在ajax请求中它将变成

url: "request-vote"

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

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

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

url: "vote.php",
$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;
//另外,请让您的脚本知道我们成功地完成了此向下投票,因此让我们将其添加到数组中

$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);
}

我认为这类问题属于我的意思是给ID一个Int(1)的数据类型,这将确保在WHERE条件下只能使用整数。而且因为您根本不检查postID在您的code@Pierre我已经根据你的建议做了修改。现在我想使用ajax自动更新投票。你能分享一个例子吗?通过自动更新投票来@MahimParsai是什么意思?@Pierre我的意思不是说数据库中的投票正在更新,而是在ajax调用后如何在前端更新它们?