0

タイトルにあるように、PDOとトークンを使用してMySQLデータベースの特定のレコードを更新し、インジェクションから保護しようとしています。

これが私のコードです:

クエリの作成に役立ついくつかの配列:

$id = 1234
$values = array ('a','b','c',);
$variables = array ($A, $B, $C);

ループを介して構築されたクエリ:

$sql =  "UPDATE table1 SET ";   
        foreach($values as $value)
        {
        $sql .="$value = :$value, ";
        }
        $sql = rtrim($sql,', ');    
        $sql .=" WHERE id = '$id'";

PDOを介したクエリの実行:

try     
{
$pdo = new PDO('mysql:host=localhost; dbname=db01', $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$stmt = $pdo->prepare($sql);
foreach(array_combine($values, $variables) as $value=>$variable)
{
$stmt->bindParam(":$value", $variable);
}

$stmt->execute();

結果:指定されたレコード($ idに一致)のすべてのフィールドが同じ値に設定されます。これは、配列にリストされている最後の変数の内容と常に等しくなります(この例では、すべてに$Cに保持されている値が含まれます)。 )。

SQLクエリをエコーすると、正しく構築されていることがわかります。

何か案は?よろしくお願いします

4

2 に答える 2

1

コメントからの拡張:

foreachループでは、は$variableあり、参照ではないため、mysqli_stmt::execute()実際には最後のを使用することになります$variable

これを回避するには、次のようなものを使用する必要があります。

$cache=array_combine($values,$variables);
foreach($cache as $value=>$variable)
{
  $stmt->bindParam(":$value",$cache[$value]);
}
于 2012-11-07T03:12:54.750 に答える
0

あなたはこのようにしなければなりません:

  foreach(array_combine($values, $variables) as $value=>$variable)
  {
    $stmt->bindParam(":$value", $variable);
    $stmt->execute();
   }

forループ内でクエリを実行します。ループが完了したら、配列の最後の値しか取得しないため、クエリを実行しないでください。一度だけ実行されます。

于 2012-11-06T06:16:49.483 に答える