フルスタックエンジニアのノウハウ
2020.03.19    2022.06.12

query、prepare、executeはどう使い分ける?

この記事の動画版はこちら(画像クリックでYoutubeに飛びます)

チャンネル登録お願いします!


今回は、PHPからPDOクラスを使ってデータベースを操作する際の「query/prepare/executeの使い分け」について解説します。



query、prepare、executeって何?


これら3つは、PDOでデータベースを操作する際に使うメソッドです。


PHPからデータベースを操作する手順は以下のようになります。


①データベースに接続する。
②実行したいSQL文をセットする。
③SQLに対してパラメーターをセットする。【任意】
④実際にSQLを実行する。
⑤結果を取得する。【任意】
⑥データーベースから切断する。


※各手順の詳細については、以下の記事で解説しています。

関連記事

PHPからデータベースを操作する手順



これらを実際にソースコードに書く際、「簡易版」と「詳細版」の2つの書き方があります。


簡易版


 簡易版は「query」を実行するだけで②③④を一気に処理してくれます。


簡易版の処理の流れ

①を実行

queryを実行(②③④が一気に実行される)

⑤を実行

⑥を実行



詳細版


 詳細版は「②prepare③bindValue④execute」という手順を行う必要があります。


詳細版の処理の流れ

①を実行

prepareを実行

bindValueを実行

executeを実行

⑤を実行

⑥を実行


つまり、「query」は簡易版で使うメソッド(②③④を一気に処理してくれる)であり、「prepare」と「execute」は詳細版で使うメソッドということです。



なぜ「簡易版」と「詳細版」が存在するのか?


簡易版/詳細版は、実行したいSQL文の中に「変動値」が入るかどうかで使い分けます。


SQL文の中に変動値が入る場合、以下のようにPHPの変数を直接連結してしまうと「SQLインジェクション攻撃」により悪意のあるSQLが実行されてしまう可能性があります。


$sql = "SELECT * FROM user WHERE name='$name'";


そのため、「プレースホルダ」という仕組みを使って、以下のように変動値を安全にSQL文に割り当てるわけですが、


$sql = "SELECT * FROM user WHERE name=:name";


ここで使うのが「prepare」と「bindValue」と「execute」なんです。



※プレースホルダについては以下の記事で詳しく解説しています。

関連記事

プレースホルダとは?SQLインジェクション攻撃を回避せよ!



使い分けの実例


使い分けは明確です。


SQL文の中に「変動値があるか、ないか」で使い分けましょう。



変動値がない場合(queryを使う)


例1)

$pdo->query('SELECT * FROM user');


例2)

$pdo->query('SET NAMES utf8');



変動値がある場合(prepare、bindValue、executeを使う)


例)

$stmt = $pdo->prepare("SELECT * FROM user WHERE name=:name");

$stmt->bindValue(':name', $name, PDO::PARAM_STR);

$stmt->execute();



現場のコツ
実際の開発では「変動値があるSQL」がほとんどですので、prepareを使うパターンに慣れておきましょう!



まとめ


 SQL文に変動値がない場合:query
 SQL文に変動値がある場合:prepare⇒bindValue⇒execute


このように使い分けましょう!


おすすめ記事