试图创建一个“;像“;类似于Facebook的系统


Trying to create a "like" system similar to Facebook

我正在使用一个PHP数组来收集添加到MySQL数据库中的用户输入。由于这是来自用户输入的信息,我使用数据库中num_rows创建的变量来确定for循环在显示数组值时运行的次数。for循环包含一个显示数组一个值的窗体和一个"赞"按钮(type=submit),并重复此窗体,直到显示完所有值(从最新到最旧),每个值后面都有一个"喜欢"按钮。

我希望用户能够点击"赞"按钮,在帖子中添加"赞"。我遇到的问题是,我的代码在每个帖子中都添加了一个"赞"(因为代码会检查是否按下了"赞"按钮,而且由于"赞"是由for循环创建的,所以每个"赞"都有相同的名称)。我试图通过给"like"按钮一个基于递增变量的名称来纠正这一问题,但如果名称是变量或数组,则该按钮似乎不起作用。

这是我的代码:

<?php
error_reporting (E_ALL ^ E_NOTICE);
session_start();
$userid = $_SESSION['userid'];
$username = $_SESSION['username'];
$userside = $_SESSION['side'];
echo "<b>Organized posts:</br><hr /></b>";
require("./postconnect.php");
$query = mysql_query("SELECT * FROM original ORDER BY postid ASC");
$numrows = mysql_num_rows($query);
$numrows = $numrows-1;
$sql = "SELECT postername FROM original ORDER BY postid ASC"; // select only the postername field from the table "original"
$result = mysql_query($sql); // process the query
$name_array = array(); // start an array
while($row = mysql_fetch_array($result)){ // cycle through each record returned
  $name_array[] = "".$row['postername'].""; // get the postername field and add to the array above
}
$sql = "SELECT post FROM original ORDER BY postid ASC"; // select only the post field from the table "original"
$result = mysql_query($sql); // process the query
$post_array = array(); // start an array
while($row = mysql_fetch_array($result)){ // cycle through each record returned
  $post_array[] = "".$row['post'].""; // get the post field and add to the array above
}
$sql = "SELECT posterside FROM original ORDER BY postid ASC"; // select only the posterside field from the table "original"
$result = mysql_query($sql); // process the query
$side_array = array(); // start an array
while($row = mysql_fetch_array($result)){ // cycle through each record returned
  $side_array[] = "".$row['posterside'].""; // get the posterside field and add to the array above
}
$sql = "SELECT likes FROM original ORDER BY postid ASC"; // select only the likes field from the table "original"
$result = mysql_query($sql); // process the query
$likes_array = array(); // start an array
while($row = mysql_fetch_array($result)){ // cycle through each record returned
  $likes_array[] = "".$row['likes'].""; // get the likes field and add to the array above
}
$i=$numrows;
for($i;$i>=0;$i--) {
    if ($side_array[$i]==1) {
        $color="red";
    }
    elseif ($side_array[$i]==2) {
        $color="blue";  
    }
    elseif ($side_array[$i]==3) {
        $color="green"; 
    }
    echo "<form action='./memberhag.php' method='post'>
            <table>
            <tr>
              <td><font color='$color'>$name_array[$i]</font> - $post_array[$i]</td>
        </tr>
        <tr>
          <td><input type='submit' name='likebtn' value='Like' /> <font color=$color>$name_array[$i]</font> has $likes_array[$i] likes!</td>
        </tr>
        </table>
        </form>";
    if ($_POST['likebtn']) {
            $numlikes = $likes_array[$i];
        $numlikes = $numlikes + 1;      
        mysql_query("UPDATE original SET likes = '$numlikes' WHERE postername = '$name_array[$i]'");

    }
}
?>

这让我困惑了很长一段时间。。。我甚至尝试过使用while循环而不是for循环。

有很多表单来做这件事是一种可能的解决方案,但我倾向于只有一个表单和几个按钮。主要问题似乎是,正如你所说,你对按钮的调用是一样的,这意味着你无法确定按下了哪个按钮。

非常基本的修复是这样做的:

<input type='submit' name='likebtn_{$i}' value='Like' />

这至少会给你一个序数,你可以用来区分按钮。然而,在这个循环中循环posts可能更好些,所以您可以这样做(假设您在这个表中有一个名为id的主键:

<input type='submit' name='likebtn_{$post['id']}' value='Like' />

啊,是的,当你修复你的POST部分(即有人按下"点赞"按钮时的部分)时,你需要读取$_POST中的内容,并解析出推送的内容。为了帮助调试,请将其临时添加到您的后处理程序中:

print_r($_POST); exit();

这将为您提供需要解码的输出(检查每个帖子的输出是否不同)。您还需要更改if语句来检测帖子;更改此项:

if ($_POST['likebtn']) {

至:

if ($_POST) {

这是必要的,因为您现在没有一个要检测的名称,所以我们现在检测数组$_POST是否包含任何内容(如果包含,我们知道这是一个后期操作)。在里面,把print_r()放在上面,看看里面有什么

现在,这里有一些你可以做的事情来改进你的代码:

  • 目前还不清楚original表的作用,所以我可能会重命名它
  • 当您已经完成SELECT * FROM original时,这个表中似乎有几个查询,所以这里的查询太多了
  • 请记住,在这样的系统中,您可能需要其他表,例如谁完成了"like"(可能称为user
  • 不要使用for循环,而是将其切换到posts表上的while循环
  • 尽量不要在echo "x"语句中放入大块HTML,因为过一段时间就会很难调试。最好跳出PHP模式,在HTML模式中使用简单的循环和变量输出

编辑,回应您的评论:

好的,我做了if($_POST){print_r},得到了其中一个帖子的Array([likebtn_4]=>Like)。:-)-Jeremy

太棒了!好吧,试试这样的东西:

if ($_POST) {
    $find = 'likebtn_';
    foreach ($_POST as $key => $value) {
        $likeKey = (int) str_replace($key, $find, '');
        if ($likeKey) {
            // If this runs, do your update against row $likeKey
            // Note that I've forced it to be an int, to avoid security issues
        }
    }
}

最重要的是,试着理解为什么这样做。如有必要,围绕它读一些书。我基本上已经遍历了post操作的关联数组,并测试了每个键(即元素名称),看看它是否包含字符串"likebtn_"。如果是,我将余数转换为整数,然后可以在UPDATE语句中使用。

这些查询中的任何一个都没有不同的逻辑。因此,显而易见(只读)的做法是将它们组合成一个语句。编写代码时,请尽可能少地编写。信不信由你,这将大大提高你的代码质量。不过,不要为了实现这一目标而牺牲清晰度,有时清晰度用更少的行来表达,有时则不然。

我假设你的数据库,你唯一的表是这样的:

|postername|post|posterside|likes|

这意味着原始表中的每一行都有如上所述的相应列。

所以。。。。

if(!empty($_POST) && !!$_POST['likebtn']) {
    //Do your likebtn stuff here.
}
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
$sql = "SELECT * FROM colums ORDER BY postid ASC";
$result = mysqli->query($sql);
while($row = $result->fetch_assoc()){
    switch($row[2]) {
        case 1:
             $color = "red";
             break;
        case 2:
             $color = "blue";
             break;
        case 3:
             $color = "green";
             break;
        default:
            //Handle when this case doesn't match
     }
//The rest of your table would go hear, remember that $row[0] is the corresponding
//postername for said row.  You will loop through rows until there are no more.
//Study Mysql injection, you are in danger of it now.  Good luck
}