とprepare()
の違いはprepare()
方法を設定して、魔法のあなたはSQLインジェクションのために保存されていることでしょう「secure=true;
」のようないくつかの内部フラグを持っているということではありません。実際には、あなたにも、あなたが間違ってそれを使用する場合prepare()
でSQLインジェクションを持つことができます。
$stmt = $db->prepare('SELECT password FROM user WHERE username = "'.$username.'"');
$stmt->execute();
// ...
を準備文のポイントは、SQLクエリの値/引数/変数は、実際のSQLクエリから送信分離されていることですMySQLサーバに転送します。この方法では、値/引数/変数は送信しようとしているSQLクエリを変更できません。これにより、入力に"='' OR 1 = 1 --"
のような値が含まれているSQLインジェクションが防止されます。
準備されたステートメントは、準備されたステートメントの値をbind_param()
のような追加のAPI呼び出しで区切って設定するデータ構造を構築しています。 SQLサーバーは "prepared"ステートメントを使用し、bind_param()
から受け取った値を使用します。潜在的な危険なデータが読み込まれた最初の値さえも読み取られる前に、クエリは読み込まれ、分析され、うまく「準備され」ています(この準備されたステートメントの期間中)。 WHERE条件を変更または弱めることはできず、別のSQLクエリを追加することも、他の行/列/テーブルを編集することもできます。
このため、コールがないため、コールを内部でprepare()
にリダイレクトするだけで安全にすることはできません。つまり、変数やユーザー入力なしで固定のSQLクエリがある場合はを使用し、変数やユーザー入力に依存するSQLクエリを持つプリペアドステートメントの場合はprepare()
を使用します。
これは後でバインド変数で埋められるプレースホルダ付きのSQL文を構築するようデータベースに指示します。おそらく[this](http://www.mysqltutorial.org/mysql-prepared-statement.aspx)は –
@MarkBakerありがとう。なぜこの段階が存在するのですか?なぜユーザーの視点からスキップできないのでしょうか?次の質問で質問を編集します。 – Griffin
このドキュメントでは、説明の節でさらに述べています: 'SQLクエリを準備し、ステートメントに対するさらなる操作に使用されるステートメントハンドルを返します。クエリは1つのSQL文で構成されていなければなりません。もしあなたがもっと「もっとうまくいく」ためには、PHPのソースコードを入手しなければなりません。 –