【PHPの基本】PDOのquery/prepareメソッドの使い分け

こんにちは、ぱすたです!今回はデータベース操作についての記事です。

ぱすた

データベースの基本操作はCRUDです。

 CRUD 機能 SQL文
Create 作成、登録 INSERT
Read 読み取り、参照 SELECT
Update 更新、変更 UPDATE
Delete 削除 DELETE

このデータベースを操作するには、2つの方法があります。

  • query()メソッドを使う
  • prepare()メソッドを使う

この記事では2つのメソッドの使い分けと、実際の使い方について紹介します。

初心者で技術メモとして残しているので、間違っているところがあったらすみません(-。-;

※PHPのバージョンは8.08で、データベースはMySQLを使用しています。

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

  1. データベースに接続する
  2. SQL文を準備する
  3. SQLを実行する
  4. SQLの結果を取得する(省略可能)
  5. データベースとの接続を終了する

PDOを使ったデータベースへの接続方法はこちらの記事にまとめています↓

【PHP】PDOでデータベースに接続する方法

queryメソッド

queryはSQL文の準備と実行を一気にしてくれる。ユーザーから値の受け渡しがなく、固定のSQL文でいける時に使う。

queryはSQLを実行するとPDOStatmentオブジェクトを返してくれる。このオブジェクトにはfetchメソッドがあるので、このメソッドでデータを取得できる。

prepareメソッド

prepareはSQL文を準備し、PDOStatmentオブジェクトを返してくれる。

ここがqueryとの大きな違いです。prepareはSQL文の準備はするが、実行はしません。

実行にはPDOStatmentオブジェクトexecuteというSQLを実行するメソッドを使います。

データの取得方法はqueryと同じです。

MEMO

prepareを使うのは、SQL文の値が変動する時です。

例えばサイトへログインするとき、メールアドレスやパスワードを入力します。入力する内容は人によって違います。

これだと固定のSQL文では対応できません。

また悪意を持った人が、入力欄にコードを書き込んでそれがSQL文にそのまま代入されると、予期しないSQLが実行されることがあります(SQLインジェクション)。

prepareはこういったコードも正しく処理してくれるので、セキュリティの観点からも変動値が入るSQL文にはprepareを使います。

実際の使い方

事前にmydbという名前のデータベースを作っておき、テーブル名はfruitsにします。

テーブルにはidとnameカラムを作り、このようにデータを挿入しておきました。

query

<?php
$dsn = 'mysql:dbname=mydb;host=127.0.0.1;charset=utf8';
$user = 'root';
$password = 'root';
try {
	$db = new PDO($dsn, $user, $password);
	//データベースに接続

	$record = $db->query('SELECT * FROM fruits');
  //queryメソッドでfruitsテーブルから全てのレコードを取り出すSQL文を実行。結果をrecordに代入。
  while ($records = $record->fetch()) {
  echo $records['name'] . "\n";
  }
  //fetchメソッドでrecordに代入された結果を、取得する。echoで出力。

  $db = null;
  //データベースから切断

} catch (PDOException $e) {
	echo 'DB接続エラー:' . $e->getMessage();
}
?>

実行結果↓

fetchは一行のレコードを取得するメソッドなので、$records = $record->fetch();echo $records[‘name’];としても最初の行のりんごしか取得できません。

なのでwhile文で繰り返し処理を行い、全ての行を取得できるようにします。

prepare

なぜかソースコードがうまく表示できなかったので、画像ですみません(-。-;

まずprepareにベースとなるSQL文をセットします。今回はfruitsテーブルのnameカラムに値を挿入するSQL文を作りました。

nameには何の値が入るか分からないので、name=?とします。これをプレースホルダと言います。

プレースホルダはこの方の記事が参考になりました↓

参考 プレースホルダとは何か?SQLインジェクション攻撃を回避せよ!実戦型プログラミングをわかりやすく

次にこの?に値を入れてSQL文を組み立てる必要があります。これはPDOStatmentオブジェクトbindValueという値をパラメータにバインドしてくれるメソッドを使います。

コード
bindValue(何番目の, 当てはめる変数 ,値の型);

「何番目の」は?の位置です。プレースホルダが何個もあるSQL文もあるので、?の位置を指定します。今回は1つ目しかないので、1にします。

当てはめる変数が?に入る値になります。今回は’パイナップル’にしました。実際はPOSTGETでユーザーが入力した値を受け取って、変数に入れることが多いです。

値の型は、?に入る値が文字列だったらPDO::PARAM_STR、数値型ならPDO::PARAM_INTにします。

このbindValueメソッドを実行すると、?に値がセットされます。

最後にexecuteメソッドでSQLを実行して、データベースから切断されます。

実行結果はこちら↓fruitsテーブルにパイナップルが挿入されてます。

まとめ

ということで今回はqueryとprepareメソッドの使い分けについて紹介しました。

セキュリティの観点からもユーザー入力があるプログラムを作るときなど、prepareを使うようにしましょう。

  • query:変動値が入らない時に使う。SQL文の準備、実行を一気に行う。
  • prepare:変動値が入る時に使う。prepare→bindValue→executeで準備、実行を分けて行う。