PDO::query、PDO::prepare、PDOStatement::fetchAll、PDOStatement::closeCursorの使い方

私はPDOもMySQLも初心者です。
マニュアル等をただ読んでるだけだとさっぱり理解が追いつきません。
そこで入門用に、必ず?使う4つをちょっとまとめてみます。


私は

$pdo = new PDO

で開始するので、以下、$pdo->という形で記述します。

1.PDO::query

$stmt = $pdo->query($sql);

「一回の関数コールの中で SQL ステートメントを実行し、このステートメントにより返された 結果セット (ある場合) を PDOStatement オブジェクトとして返します」。


オーソドックスなSQL文(SQLステートメント)の実行方法です。
同じSQL文を複数回実行する場合には、仕組上2.PDO::prepareの方が良いパフォーマンスを得られるとのこと。


別途、「クエリ内のデータは適切にエスケープ する必要があります」。SQLインジェクション対策が必要です。



2.PDO::prepare

$stmt = $pdo->prepare($sql);
$stmt->execute();

PDO::prepareは、「PDOStatement::executeメソッドによって実行される SQL ステートメントを準備します」。


つまり、PDO::prepareであらかじめ実行可能なSQL文(プリペアードステートメント)にコンパイル?します。その上でプリペアードステートメントPDOStatement::executeで実行する方法です。


PDO::queryと較べ、何か嬉しいかというと以下の2点。
1.「パラメータに手動でクオートする必要がなくなるので SQL インジェクション攻撃から保護する助けになります」
2.「異なるパラメータを用いて複数回実行されるような文に対し PDO::prepare() と PDOStatement::execute() をコールすることで、 ドライバがクライアントまたはサーバ側にクエリプランやメタ情報を キャッシュさせるよう調整するため、 アプリケーションのパフォーマンスを最適化します。」



ただし2.について。
MySQL5.1.17未満ではプリペアードステートメントを使ってもクエリキャッシュが効かない?らしいです。


▽PDOの Prepared Statementと MySQLの Query Cache(floatingdays)
 http://fdays.blogspot.com/2009/02/pdo-prepared-statement-mysql-query.html


確認したところ、MySQL5.1.17以降だったので問題なさそうです。
ただそもそもクエリキャッシュがオンになっているかわからなかったので、設定を確認しました。


以下のSQL文で、「MySQL サーバでクエリキャッシュを行っているかどうかを確認」します。

SHOW VARIABLES LIKE 'have_query_cache';

have_query_cacheがYESと返ってきたので、クエリキャッシュをを使う設定になっているようです。



3.PDOStatement::fetchAll

$result = $stmt->fetchAll();

PDOStatement->fetchAllは、「結果セットに残っている全ての行を含む配列を返します」。
つまり1.PDO::queryや2.PDO::preparePDOStatement::executeで得られた結果セットから配列を取り出して変数につっこむ為に必要ということですね。


fetchAllだけでなくfetchもあるので、適宜使い分けると。
なお「大きな結果セットをフェッチするためにこのメソッド(PDOStatement->fetchAll)を使用することは、システムとネットワークリソースに大量の要求を行うことに」なるので避けるように、とあります。


4.PDOStatement::closeCursor

$stmt->closeCursor();

PDOStatement::closeCursorは、「他の SQL ステートメントを発行できるようにサーバへの接続を解放します」(「 カーソルを閉じてステートメントを再実行できるように」します)。

1.PDO::query及び2.PDO::prepareを「次にコールする前に結果セット内の全てのデータを取得しない場合、そのコールは失敗します」。


▽PDO で複数の SQL 文を連続実行するとエラーになる理由(れぶろぐ)
 http://www.revulo.com/blog/20060522.html



あとはマニュアルや以下の記事のサンプルソースを見ながらだったら、書けるかな?


MySQL(PDO)による簡易掲示板 ? PHP入門(データベース2)(イクケン)
 http://labo.iix.co.jp/?p=811