2012-06-17 104 views
1

我有以下的PHP脚本:给予好评/ Downvote系统

<?php 
$vote_type = $_GET['type']; 
$book = $_GET['book']; 
$id = $_GET['id']; 


include 'pagehead.php'; 

$tracker_table = $book.'VoteTrack'; 
$username = $_SESSION['username']; 

session_start(); 
if ($_SESSION['username'] == null) { 
echo 'You must be logged in to vote'; 
echo '<br>'; 
echo '<a href="lesson.php?book='.$book.'&id='.$id.'">'; 
echo 'Return to lesson'; 
echo '</a>'; 
die(); 
} 

include 'mysqlserver.php'; 
$con = mysql_connect($mysql_host, $mysql_username, $mysql_password); 
if (!$con){ 
die ('Failed to connect to the database'); 
} 

mysql_select_db("a6595899_s", $con); 


$data_query = "SELECT * FROM $book WHERE id=$id"; 
$lesson_data = mysql_query($data_query); 
$lesson_array = mysql_fetch_assoc($lesson_data); 

$vote_cop_query = "SELECT * FROM $tracker_table WHERE user='$username' AND id=$id"; 
$vote_cop_data = mysql_query($vote_cop_query); 
$vote_cop = mysql_fetch_assoc($vote_cop_data); 

if (mysql_num_rows($vote_cop_data) != 0 && $vote_type == 'up' && $vote_cop['has'] == 1) { 
echo 'You have already upvoted this lesson.'; 
echo '<br>'; 
echo '<a href="lesson.php?book='.$book.'&id='.$id.'">'; 
echo 'Return to lesson'; 
echo '</a>'; 
die(); 
} elseif (mysql_num_rows($vote_cop_data) != 0 && $vote_type == 'down' && $vote_cop['has'] == 2) { 
echo 'You have already downvoted this lesson.'; 
echo '<br>'; 
echo '<a href="lesson.php?book='.$book.'&id='.$id.'">'; 
echo 'Return to lesson'; 
echo '</a>'; 
die(); 
} 

$vote_count = $lesson_array['votes']; 
if ($vote_type == 'up') { 
$vote_count++; 
$has_type = 1; 
} elseif ($vote_type == 'down') { 
$vote_count--; 
$has_type = 2; 
} else { 
die('Vote type not specified.'); 
} 

$new_or = mysql_num_rows($vote_cop_data); 

if ($new_or == 0) { 
$track_query = "INSERT INTO $tracker_table (user, id, has) 
VALUES ('$username', $id, $has_type)"; 
} else { 
$track_query = "UPDATE $tracker_table SET has=$has_type WHERE user='$username' AND id=$id"; 
} 
mysql_query($track_query); 


//actually cast vote.. 
$update_query = "UPDATE $book SET votes=$vote_count WHERE id=$id"; 
mysql_query($update_query); 

echo 'Your vote has been submitted!'; 
echo '<br>'; 
echo '<a href="lesson.php?book='.$book.'&id='.$id.'">'; 
echo 'Return to lesson'; 
echo'</a>'; 


?> 

这是一个非常简单的投票向上/和投降系统。不幸的是,它在某些情况下发生故障。假设我正在阅读一个我认为很好的课程,所以我将它投票。后来,我意识到这个教训实在太糟糕了,所以我对它低估了。在我第一次投票之后,这一课有一点。在我冷静下来之后,它又有了0。逻辑表明,我应该能够再次下课,给它-1分。我的代码不会允许这样做,因为我的脚本只是说连续两次不允许同一个动作。 我用什么数学来解决这个问题?

+3

请不要使用'mysql_ *'函数编写新代码。他们不再维护,社区已经开始[弃用程序](http://goo.gl/KJveJ)。查看[*红色框*](http://goo.gl/GPmFd)?相反,您应该了解[准备好的语句](http://goo.gl/vn8zQ)并使用[PDO](http – gorelative

+0

@Geoist记录,这是我的代码,它完全是从头开始编写的,我只需要帮助在允许某人在upvoting之后两次downvote的代码,或者反之亦然。 – Jaxkr

+0

查看http://amix.dk/blog/post/19588,对Reddit的排名算法的一个非常好的分析。不是直接回答你的 – dimo414

回答

8

问题是,在这里,你在用户的活动downvoted自己upvote后更新用户的活动。

$track_query = "UPDATE $tracker_table SET has=$has_type WHERE user='$username' AND id=$id"; 

你应该做的是从表中删除记录而不是更新它,然后继续修改得分。这样,您做的下一个投票将是您所做的“第一次”投票。

或者,您可以有第三个vote_cop类型,称为'无效'或'撤销'或其他,然后相应地修改投票警察。

见下面我的建议:

$hasVotedBefore = mysql_num_rows($vote_cop_data) != 0; 

if ($hasVotedBefore) { 

    switch ($vote_cop_data['has']) { 
    case 0: 
    $vote_cop_type = 'revoked'; // Not really neccessary to do this, but just here for show. 
    break;  
    case 1: 
    $vote_cop_type = 'up'; 
    break; 
    case 2: 
    $vote_cop_type = 'down'; 
    break;  
    default: 
    break; 

    if ($vote_type == $vote_cop_type) { // We're here because we voted before and our new vote is the same as the old one. 

    if ($vote_type == 'up') { 

     echo 'You have already upvoted this lesson.'; 
     echo '<br>'; 
     echo '<a href="lesson.php?book='.$book.'&id='.$id.'">'; 
     echo 'Return to lesson'; 
     echo '</a>'; 
     die(); 

    } elseif ($vote_type == 'down') { 

     echo 'You have already downvoted this lesson.'; 
     echo '<br>'; 
     echo '<a href="lesson.php?book='.$book.'&id='.$id.'">'; 
     echo 'Return to lesson'; 
     echo '</a>'; 
     die(); 
    } 

    } else { // Were here because we've voted before, and our new vote is the opposite of the old vote. 

    // Update vote_cop row in the database so the 'has' column is 0 (value of a revoked vote) 
    // This way, for future votes, we know the user has voted before, but revoked their vote. 
    $track_query = "UPDATE $tracker_table SET has=0 WHERE user='$username' AND id=$id"; 
    mysql_query($track_query); 
    } 
} else { // We're here because we never voted before. 

    $track_query = "INSERT INTO $tracker_table (user, id, has) VALUES ('$username', $id, $vote_type)"; 
    mysql_query($track_query); 
} 

// TODO: actually cast vote.. 
+0

太棒了,非常感谢 – Jaxkr

+1

我添加了一个提纲如果上面的建议不够好, – 2012-06-17 04:45:12

+0

你摇滚。现在重新编写我的代码。 – Jaxkr