SQL文を打つとき、
SQL文のどこかに、入力値を変数として、入れているなら、
例えば、post送信で、テーブル名を取得している場合など、
$table-name = $_POST[$table];
$sql = “SELECT * FROM $table-name”;
入力値に、予期せぬSQL文などが入った場合、それが実行され、
最悪の場合、カラムやテーブルのデータが消えるということもある。
このような、SQL文での攻撃を、SQLインジェクションという。
詳しくは、以下を参照
https://blog.senseshare.jp/placeholder.html
これを防ぐために、SQLを送信する前に、文字列を置換して、クエリを送信する仕組みがある。
これを「プリペアードステートメント」と言う。
準備された宣言?
予約文というらしい。
これを使うのに、まずはデータをプレースホルダーに、バインドする。
バインドの仕方は、
ステートメントに、PDOオブジェクト ($dbh:どこかで宣言済みとする)からprepareメソッドを呼び出し、
そこに、SQL文を書く。
ex) tableから、user = name のデータを全て取得したい場合、
$stmt = $dbh->prepare(“SELECT * FROM table WHERE user = :name”);
$stmt->bindParam(‘:name’, $user_name);
$stmt->execute(); // 準備したSQLを実行する。
$user_nameは入力フォームから取得した値など。
$user_nameの部分は、ユーザーが入力した値なので、これを:nameと言うデータに置き換える。
:name と言うプレースホルダーに、$user_nameをバインドしたと言うこと。
コロンを使う方法以外に?を使う方法がある。
$stmt = $dbh->prepare(“SELECT * FROM table WHERE name = ?”);
$stmt->bindParam(1, $user_name); // 数字は?が複数ある場合の、順番を指す
$stmt->execute();
データを挿入する場合も、取得する場合もSQLへの変数はバインドすること。
![]() |
|
![]() |
|