mysqli_stmt :: prepareは、 mysqli拡張で使用される方法で使用されています。前処理ステートメントは、SQLクエリ文字列を直接使用する場合と比較して、SQL注入のリスクを減らします。これは、SQLを実行すると、ユーザーによるコンテンツ入力がクエリ文字列に直接スプライスされるのではなく、バインディングパラメーターとして渡されるためです。
<span><span><span class="hljs-variable">$conn</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">mysqli</span></span><span>(</span><span><span class="hljs-variable">$host</span></span><span>, </span><span><span class="hljs-variable">$user</span></span><span>, </span><span><span class="hljs-variable">$password</span></span><span>, </span><span><span class="hljs-variable">$database</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$conn</span></span><span>->connect_error) {
</span><span><span class="hljs-keyword">die</span></span><span>(</span><span><span class="hljs-string">"Connection failed: "</span></span><span> . </span><span><span class="hljs-variable">$conn</span></span><span>->connect_error);
}
</span><span><span class="hljs-variable">$stmt</span></span><span> = </span><span><span class="hljs-variable">$conn</span></span><span>-></span><span><span class="hljs-title function_ invoke__">prepare</span></span><span>(</span><span><span class="hljs-string">"SELECT * FROM users WHERE username = ? AND password = ?"</span></span><span>);
</span></span>
上記のコードでは、SQLクエリには2つの疑問符( ? )が含まれています。これは、後続のバインドされたパラメーターを受け入れるプレースホルダーです。
プリプロセシングステートメントでは、 bind_param()メソッドを使用して、ユーザーの入力値をプレースホルダーにバインドします。現時点では、バインドされたパラメーター値はSQLステートメントに直接挿入されませんが、プリプロセッシングステートメントに渡されます。 bind_param()メソッドには、データ型の指定子とバインドされる変数の2つのパラメーターが必要です。
一般的なデータ型仕様は次のとおりです。
I :integer(int)
D :ダブル精度フローティングポイント(ダブル)
S :文字列(文字列)
B :BLOB(バイナリデータ)
<span><span><span class="hljs-variable">$username</span></span><span> = </span><span><span class="hljs-string">'john_doe'</span></span><span>;
</span><span><span class="hljs-variable">$password</span></span><span> = </span><span><span class="hljs-string">'password123'</span></span><span>;
</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">bind_param</span></span><span>(</span><span><span class="hljs-string">'ss'</span></span><span>, </span><span><span class="hljs-variable">$username</span></span><span>, </span><span><span class="hljs-variable">$password</span></span><span>);
</span></span>
この例では、 「ss」とは、両方のパラメーターバインドが文字列型であることを意味します。パラメーター$ usernameと$パスワードは、 SQLクエリのプレースホルダーに安全にバインドされます。
パラメーターバインディングが完了すると、preprocessingステートメントを実行するためにexecute()メソッドが呼び出されます。バインドされたパラメータータイプが正しい場合、実行ステートメントは正常に実行されます。
<span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">execute</span></span><span>();
</span></span>
execute()メソッドは、ステートメントが正常に実行されるかどうかを示すブール値を返します。クエリ結果を取得する必要がある場合は、 get_result()メソッド(選択したクエリ用)を使用して実行結果を取得できます。
選択されたステートメントの場合、前処理ステートメントを実行した後、通常、クエリの結果を取得する必要があります。 get_result()メソッドを使用して、クエリ結果をmysqli_resultオブジェクトに変換し、そこからデータを取得できます。
<span><span><span class="hljs-variable">$result</span></span><span> = </span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">get_result</span></span><span>();
</span><span><span class="hljs-keyword">while</span></span><span> (</span><span><span class="hljs-variable">$row</span></span><span> = </span><span><span class="hljs-variable">$result</span></span><span>-></span><span><span class="hljs-title function_ invoke__">fetch_assoc</span></span><span>()) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-variable">$row</span></span><span>[</span><span><span class="hljs-string">'username'</span></span><span>] . </span><span><span class="hljs-string">' - '</span></span><span> . </span><span><span class="hljs-variable">$row</span></span><span>[</span><span><span class="hljs-string">'email'</span></span><span>] . </span><span><span class="hljs-string">'<br>'</span></span><span>;
}
</span></span>
この例では、クエリの結果は行で抽出され、ユーザー名と電子メールが出力されます。
前処理ステートメントはSQL注入を防ぐことができますが、実際の開発では依然としてさまざまなエラーが発生する可能性があります。効果的なデバッグのために、エラー方法を使用して関連するエラー情報を取得できます。
<span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$stmt</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span>) {
</span><span><span class="hljs-keyword">die</span></span><span>(</span><span><span class="hljs-string">'Error preparing statement: '</span></span><span> . </span><span><span class="hljs-variable">$conn</span></span><span>->error);
}
</span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">execute</span></span><span>()) {
</span><span><span class="hljs-keyword">die</span></span><span>(</span><span><span class="hljs-string">'Execute error: '</span></span><span> . </span><span><span class="hljs-variable">$stmt</span></span><span>->error);
}
</span></span>
ここでは、conn->エラーとstmt->エラーを使用して、データベース接続と実行ステートメントのエラー情報をキャプチャします。これは、問題をタイムリーに発見して解決するのに役立ちます。
プリプロセシングステートメントを使用した後、 close()メソッドを呼び出して、ステートメントとデータベース接続を閉じてリソースを解放する必要があります。
<span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">close</span></span><span>();
</span><span><span class="hljs-variable">$conn</span></span><span>-></span><span><span class="hljs-title function_ invoke__">close</span></span><span>();
</span></span>
これは良いプログラミング習慣であるだけでなく、リソースの漏れを効果的に回避します。
関連タグ:
mysqli_stmt