1

PHP配列を使用して、MySQLデータベースに追加されたユーザー入力を収集しています。これはユーザー入力からの情報であるため、データベースのnum_rowsによって作成された変数を使用して、配列値の表示でforループが実行される回数を決定しています。forループには、配列の1つの値を表示するフォームと「いいね」ボタン(type = submit)が含まれ、すべての値が表示されるまで(新しいものから古いものへ)このフォームを繰り返し、「いいね」ボタンが続きます各。

ユーザーが「いいね」ボタンをクリックして、その投稿に「いいね」を追加できるようにしたいと思います。私が遭遇した問題は、私が持っているコードがすべての投稿に「いいね」を追加していることです(コードは「いいね」ボタンが押されたかどうかを確認し、「いいね」ボタンはforループの場合、すべての「いいね」ボタンは同じ名前です)。「いいね」ボタンに増分変数に基づいた名前を付けることでこれを修正しようとしましたが、名前が変数または配列の場合、ボタンは機能しないようです。

これが私のコードです:

<?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]'");


    }
}

?>

これは私をかなり長い間困惑させました...私はforループの代わりにwhileループを使用しようとさえしました。

4

2 に答える 2

4

これを行うためのフォームがたくさんあることは1つの可能な解決策ですが、私は1つのフォームといくつかのボタンだけを持っている傾向があります。主な問題は、あなたが言うように、ボタンを同じものと呼んでいることです。つまり、どのボタンが押されたかを判断する方法がありません。

非常に基本的な修正は、これを行うことです。

<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) {

検出する名前が1つではないため、これが必要です。配列$_POSTに何かが含まれているかどうかを検出します(含まれている場合は、これが事後操作であることがわかります)。この中に、上記を入れて、中身print_r()を確認してください。

ここで、コードを改善するためにできることがいくつかあります。

  • テーブルが何をするのかはっきりしないoriginalので、おそらく名前を変更します。
  • すでに実行している場合は、このテーブルからいくつかのクエリがあるようです。SELECT * FROM originalしたがって、ここにはクエリが多すぎます。
  • このようなシステムでは、誰が「いいね」をしたかなど、他のテーブルが必要になる可能性があることに注意してください(おそらく呼ばれるuser
  • ループではなくfor、投稿テーブルのwhileループに切り替えます。
  • echo "x"しばらくするとデバッグが困難になるため、ステートメントにHTMLの大きなブロックを含めないようにしてください。PHPモードから抜け出し、HTMLモードで単純なループと変数出力を使用する方がおそらく良いでしょう。

コメントに応じて編集します。

わかりました。if($ _ POST){print_r}を実行し、投稿の1つに対してArray([likebtn_4] => Like)を取得しました。:-) –ジェレミー

素晴らしい!OK、次のようなものを試してください:

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ステートメントで使用することができます。

于 2012-08-04T11:02:10.760 に答える
2

これらのクエリのいずれにも、文字通り異なるロジックはありません。したがって、明らかに(読み取り専用)行うことは、それらを1つのステートメントに結合することです。コードを書くときは、できるだけ少なく書いてください。信じられないかもしれませんが、これによりコードの品質が大幅に向上します。ただし、この目標を達成するために明快さを犠牲にしないでください。明快さがより少ない行で表現される場合もあれば、そうでない場合もあります。

私はあなたのdbを想定するつもりです、そしてあなたの唯一のテーブルはこの形をしています:

|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
}
于 2012-08-04T11:26:39.383 に答える