$stmt = $pdo->prepare('select * from user where id=?'); $id = 1; $stmt->bindParam(1,$id); $stmt - >execute();
<span style="font-size:14px;" data-filtered="filtered"></span>
この場合、PHP は単純に SQL ステートメントを mysql サーバーに送信します。これは、mysql_real_escape_string を通常使用して文字列をエスケープし、それを SQL ステートメントに結合するのと何ら変わりません。 PDO ローカル ドライバーによってエスケープされます)、明らかにこの場合でも SQL インジェクションを引き起こす可能性があります。つまり、pdo prepare の mysql_real_escape_string がローカルのシングルバイト文字セットを使用してクエリを操作するために PHP でローカルに呼び出されます。マルチバイトでエンコードされた変数を渡しても、依然として SQL インジェクションの脆弱性が発生する可能性があります (php 5.3.6 より前のバージョンの問題の 1 つであり、PDO を使用する場合に php 5.3.6 以降にアップグレードすることが推奨される理由が説明されています)。 DSN 文字列で文字セットを指定する場合、正しいエスケープは、mysql サーバーの文字セットを指定し、変数を MySQL サーバーに送信して文字エスケープを完了することです。 PDO には PDO::ATTR_EMULATE_PREPARES という名前のパラメータがあり、ローカルで準備をシミュレートするために PHP を使用するかどうかを示します。このパラメータのデフォルト値は不明です。また、先ほどキャプチャしたパケット キャプチャと分析の結果によると、PHP 5.3.6 以降です。デフォルトでは引き続きローカル変数を使用し、それらを SQL に結合して MySQL サーバーに送信します。この値を false に設定します
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);$stmt = $pdo->prepare('select * from user where id=?'); $id = 1; $stmt->bindParam(1,$id); $stmt - >execute();
$pdo = などの charset 属性を指定する必要があります。 new PDO('mysql:host=localhost;dbname=test
;charset=utf8', 'root');
次に、DSN で charset が指定されている場合、次の質問があります。 set names
はい、set names
A。クライアント (PHP プログラム) が送信したエンコーディング
B. mysql サーバーに、クライアントが結果に必要なエンコーディングを伝えます つまり、データテーブルがgbk文字セットを使用し、PHPプログラムがUTF-8エンコーディングを使用する場合、クエリを実行する前にset names utf8を実行して、mysqlサーバーに正しくエンコードするように指示できます。プログラム内でエンコードを変換する必要があります。このようにして、クエリを utf-8 エンコーディングで mysql サーバーに送信し、取得される結果も utf-8 エンコーディングになります。これにより、プログラム内の変換エンコードの問題が解消され、文字化けしたコードが生成されることはありません。 では、DSN で文字セットを指定する役割は何でしょうか? それは、エスケープ時にローカルドライバーが指定された文字セットを使用することを PDO に伝えるだけです (mysql サーバーの通信文字セットは設定しません)。 mysql サーバーを設定します。通信文字セットの場合は、set names 関連する推奨事項:
以上がMySQL への PDO 接続がインジェクションを妨げる理由の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。