PDO:プレースホルダ、bindValue
プレースホルダ
SQL文で、doc_id を変数で指定したいとします。$doc_id=1; $query = "SELECT * FROM doc_data WHERE doc_id={$doc_id}";と書くと、$doc_id 部分に数値以外を入れられると困ったことになります。 # 危険な文字列を挿入して、データベースに攻撃を仕掛けることを、 # SQLインジェクションといいます。 # PDO では、複数のコマンドの挿入を拒否するなどのガードはありますが、 # 危険であることに変わりはありません。 入力文字列から危険部分を除外する仕組みが「プレースホルダ」です。$doc_id=1; $query = 'SELECT * FROM doc_data WHERE doc_id=?'; $sth = $this->db->prepare($query); $sth->execute(array($doc_id));# prepare, execute 自体の説明は次章で行います。 $query の中の '?' がプレースホルダで、 実際の値は execute の引数で設定します。 execute は引数から危険な文字列を無害化してから実行します。 こうして、$query に文字列を直接挿入されることを阻止できます。 なお、 指定するデータが複数ある場合は、 ? の並び順と、execute の引数の配列の並び順を揃える必要があります。
名前付きプレースホルダ
PDO では、? を名前付き文字列に置き換えることができます。$doc_id=1; $query = 'SELECT * FROM doc_data WHERE doc_id=:doc_id';'?'部分が ':doc_id' に置き換わっています。 実際の値は、bindValue で設定します。$doc_id=1; $sth->bindValue(':doc_id', $doc_id, PDO::PARAM_INT);こうしておけば、プレースホルダと実際の値の指定の並び順を気にする必要が無くなります。 # 指定値が大量にある時や、SQL文を条件によって動的に変える場合などでも迷うことが無くなるでしょう。 bindValue の詳細は後述します。
bindValue
書式は、public PDOStatement::bindValue(string|int $param, mixed $value, int $type = PDO::PARAM_STR): bool
| $param | 対応する名前付きプレースホルダ |
| $value | 設定する値 |
| $type | データベース・カラムの型 |
$doc_id=1;
$query = 'SELECT * FROM doc_data WHERE doc_id=:doc_id';
$sth = $this->db->prepare($query);
$sth->bindValue(':doc_id', $doc_id, PDO::PARAM_INT);
$sth->execute();
になります。
実行後、データを取り出す方法については、次章で説明します。