のいじーメモ

勉強したことを忘れないうちにメモしていくためのブログ

PDOの説明

自分なりにPDOについて勉強したのでここにまとめます。

作成したサンプルコード

 

<?php
$db = new PDO('mysql:host=localhost;dbname=db_name;charset=utf8','user','password');
$db->setAttribute ( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

$loginid = "var";
$sql = "SELECT * from users WHERE loginid= :loginid ";

$statement = $db->prepare($sql);

$statement->bindValue(':loginid',$loginid,PDO::PARAM_STR);
$statement->execute();

while($user = $statement->fetch(PDO::FETCH_ASSOC)){

echo $user["loginid"] . "<br>";
}


PDO (PHP Data Objects)

データアクセス抽象化レイヤーと言われ、アプリケーションとDBMS(データベース管理システム)の間に入ってDBMSの違いを意識せずにアプリケーションを作成するもの。
データベースの違いを意識しないで同じ書き方で使える。

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

エミュレーションがONの場合のみ, ; 区切りで複数のSQL文を1つのクエリで実行することができる.
エミュレートの設定がONだと動的プレースホルダになり、OFFだと静的プレースホルダになる。


ユーザー入力を受け取ってSQL文を動的に生成する場合は プリペアドステートメントプレースホルダ を使わなければならない.

プレースホルダ:
直訳すると「場所取り」.何かユーザ入力を当てはめる場所としてあらかじめ確保しておくもの.
プリペアドステートメント:
直訳すると「予約文」.文を予約したもの.通常,「予約文」は「場所取り」を使うために作られる.もし「場所取り」が無ければ普通に PDO::query などで実行するだけで十分なためである.
プレースホルダには2種類あり,疑問符プレースホルダ を使う方法と, 名前付きプレースホルダ を使う方法がある.もしこれらが混ざってしまうと

SQLSTATE[HY093]: Invalid parameter number: mixed named and positional parameters

が発生するので、どちらか一方のみを選択すること.

動的プレースホルダと静的プレースホルダの違い

IPAの出している「安全なSQLの呼び出し方」では、
静的プレースホルダは、SQL文をデータベースエンジン側にあらかじめ送信して、実行前にSQL文の構文解析などを準備しておく方式です。 SQL 実行の段階で、実際のパラメータの値をデータ
ベースエンジン側に送信し、データベースエンジン側がバインド処理します。
動的プレースホルダは、パラメータのバインド処理をデータベースエンジン側で行うのではなく、アプリケーション側のライブラリ内で実行する方式です。
と説明されている。

参考URL
IPA 安全なSQLの呼び出し方
https://www.ipa.go.jp/files/000017320.pdf
qiita PDOの静的プレースホルダと動的プレースホルダの違いを確認する
http://qiita.com/7968/items/7ddd59b94eb5a4fb6eaf

バインド機構

SQLインジェクションを防ぐために、プログラムのソースコードSQL文の雛(ひな)型の中に変数の場所を示す記号(プレースホルダと呼ばれる)を置いた後、実際の値を割り当てる仕組み。
入力値中の特殊記号も単なる値として渡されるためエスケープ処理なしで安全にSQL文を発行することが可能となる。
データベースシステムやプログラム言語によっては、この機構が用意されているものもありSQLインジェクション対策として有用である。

 

bindValue:値をバインドする 実行する前に値をバインドする
bindParam:変数をバインドする 実際に値を評価するのはexecute()の時。

基本的にbindValue推奨
理由:実行後にバインドした変数が文字列型にされる仕様もあるから
参考URL
http://qiita.com/_dozen_/items/e3c00a0a581378a4cc70

ということで値をバインドする。

$statement->bindValue(':loginid',$loginid,PDO::PARAM_STR);

 参考URL
qiita bindValueとbindParamの違い
http://piyopiyocs.blog115.fc2.com/blog-entry-656.html
qiita PHPでデータベースに接続するときのまとめ
http://qiita.com/mpyw/items/b00b72c5c95aac573b71