0

重複の可能性:
PHP PDO ステートメントは、テーブル名をパラメーターとして受け入れることができますか?

ユーザーが自分のサイトに登録してログインできるようにするスクリプトを書いています。SQLインジェクションを防ぐために、PDOの準備と実行を使用しています。

次のようにクエリを手動で作成します。

$a_query = "SELECT COUNT(*) FROM ". $login_table . " 
WHERE `username` = ". $my_username . "  
AND `password = " . $my_hash ;
$result_1 = $db->prepare($a_query);
$result_1->execute();

しかし、このように準備を正しく使用しようとすると、そうではありません:

$a_query = "SELECT COUNT(*) FROM :table 
WHERE `username` = :name
AND `password = :pass ;"
$result_1 = $db->prepare($a_query);
$result_1->bindParam(":table", $login_table);
$result_1->bindParam(":name", $my_username);
$result_1->bindParam(":pass", $my_hash);
$result_1->execute();

$result_1->errorInfo[2] から取得したエラー メッセージは次のとおりです。

You have an error in your SQL syntax; check the manual that 
corresponds to your MySQL server version for the right syntax 
to use near ''customerlogin' WHERE `username` = 'guest' AND `password`
= 'qwerty' at line 1

ご覧のとおり、prepare() はクエリを mysql に送信する前に、不思議なことにクエリの最初の部分を切り取っています。

これを修正する理由と方法を誰かに説明してもらえますか?

4

1 に答える 1

0

ご覧のとおり、prepare()は、クエリの最初の部分を不思議なことに切り取ってから、mysqlに送信します。

そうではありません。実際にそれを行うのはエラーメッセージハンドラーであり、クエリの関連部分のみを表示しようとします。通常、このようなエラーメッセージは、「この部分の直前のクエリを見てください」という意味です。つまり、クエリので指摘し:tableます。

プリペアドステートメントは識別子をサポートしていないため、クエリは機能しません。

PDOは、他の生のAPIと同様に、実際のクエリには不十分です。開発者は、生のAPIメソッドではなく、アプリケーションコードでデータベース抽象化ライブラリメソッドを使用する必要があります。

それは人生をはるかに楽にし、コードを短くします。たとえば、コード全体を2行にまとめることができます。

$sql  = "SELECT COUNT(*) FROM ?n WHERE `username` = ?s AND `password = ?s";
$data = $db->getOne($sql, $login_table, $my_username, $my_hash);

また、生のPDOを使用する画面全体のコードよりも安全です。

于 2013-01-31T12:41:33.187 に答える