2

フィールドとフィールドを含むユーザーテーブルとid、ユーザーがさまざまな Web フォームを介して変更できるさまざまなタイプのユーザーの詳細を格納する他の 10 個のフィールドがあります。これらのフィールドの一部のサブセットに対して POST された変更された値を取得し、POST データで受信されたフィールドのみを更新する PHP スクリプトが必要です。私は、これを吸わない方法で行うのは驚くほど難しいと思っています。このアプリケーションの残りの部分では、すべてのデータベース対話に mysqli を使用するため、mysqli ベースのソリューションが強く推奨されます。

これまでに検討して却下したオプションは次のとおりです。

1)UPDATEPOSTデータで提供されるすべてのフィールドに対して個別のクエリを実行します-ええ、1回のクエリで実行できる何かのためにデータベースに最大10回アクセスしたくありません。

2)フィールド名をフィールドのデータ型にマッピングする辞書を用意し、提供されたフィールドをループしてクエリを繰り返し作成し、それらがテキストフィールドであるかどうかを確認mysqli_real_escape_stringし、文字列フィールドを呼び出し、それ以外の場合は他のフィールドをサニタイズします(たとえば、タイプごとに)チェックまたはsprintf'%i' プレースホルダーを使用)。-うん!注意していれば、おそらく安全にこの方法で行うことができますが、この種のアプローチを使用する習慣をつけたくありません。不注意であると、SQL インジェクションにさらされる可能性があるからです。パラメータ化されたクエリは危険なほど失敗する可能性はありませんが、このアプローチは危険です。私の理想は、データを手動で SQL クエリに連結せず、常にパラメータ化されたクエリに依存することです。Python などの他の言語のデータベース ライブラリ

3) パラメータ化されたクエリを使用する - これは私の理想です。外部から提供されたすべてのデータをbind_parammysqli ステートメント オブジェクトのメソッドを介してクエリに挿入する限り、SQL インジェクションの影響を受けず、そうする必要がないからです。サニタイズについて心配していますが、ここではパラメーター化されたクエリを使用することは不可能のようです。問題はbind_param、最初の引数以降のすべての引数が参照によって渡されるため、データを変数として渡す必要があることです。プレースホルダーを使用してかなりエレガントに反復的にクエリを作成できます。その間、 (など)?の最初の引数として渡される型の文字列を作成しますが、実行時にどちらを選択するかを確認する方法はありません。私が渡す10個のフィールド( 10 ^ 2ケースのステートメントがない限り)。bind_param'ssiddsi'bind_paramsswitch

引数として渡す変数を実行時に選択できる、行方不明の PHP 言語構造 (配列のアンパックに似たもの) はありますbind_paramか? または、この単純な問題をきれいかつ安全に解決できる、私が考慮していない他のアプローチがありますか?

4

2 に答える 2

2

私のSafeMySQL ライブラリを使用して、2 と 3 を簡単に組み合わせることができます。コードは次のようになります

$allowed = array('title','url','body','rating','term','type');
$data    = $db->filterArray($_POST,$allowed);
$sql     = "UPDATE table SET ?u WHERE id=?i";
$db->query($sql, $data, $_POST['id']);

array はこれらすべてのフィールドを必ずしも更新するわけではないことに注意してください$allowed- POST フィールドを除外するだけです。したがって、id と url のみの $_POST でも正しく更新されます。

それにもかかわらず、準備されたステートメントを使用することは、面倒ではありますが、かなり可能です。

于 2013-01-24T20:38:10.303 に答える
-2

以下のコードを参照してください

public function update($data, $table, $where) {
    $data_str = '' ;
    foreach ($data as $column => $value) {
        //append comma each time after first item
        if (!empty($data_str)) $data_str .= ', ' ;
        $data_str .= "$column = $value" ;
    }
    $sql = "UPDATE $table SET $data_str WHERE $where";
    mysqli_query($sql) or die(mysqli_error());
    return true;
}

$data は配列です。あなたの場合は $_POST です。

$_POST 配列から保存するデータをより具体的にしたい場合は、許可された列の配列を定義できます。例えば、

$allowed = array('id', 'username', 'email', 'password');

これにより、 $_POST 配列をフィルタリングして update() 関数に渡すことができます。

于 2016-06-17T18:11:44.170 に答える