サイトアイコン スグブログ

【PHP基礎】PDOのprepareとqueryでSQL文を変数に格納する

スクリプト

PHPでprepareやqueryを使用したいけど、よくわかりません。プレースフォルダーが上手くいきません。

このような悩みも解決します。実例をつけながら丁寧に解説します。

この記事を最後まで読んでprepareやqueryの特徴などを理解して、試して見て下さい。

PHPでデータベースにアクセスし、「値を操作」したい場合、「メソッド」が必要になります。

値を操作するとは、下記などです。

メソッドとはDBを操作する命令文です。ここでのメソッドには2種類あります。下記になります。

  1. prepare
  2. query

PDOのprepareとqueryでSQL文を変数に格納する

DBにPDOでアクセスするインスタンスを、新しく作成し格納した変数を「$db」とします。

PDOとはどんなDBにも同じ形でアクセスできる為に出来た、DBアクセスの規格のようなものです。

インスタンスとは、設計書からできたものです。PDOというDB接続の設計書から出来た、今回のものです。

DBの中に「users」テーブルを作成しています。詳細は下記にしました。

id name score
1user_147
2user_224
DBのusersテーブル

PDOから出来たインスタンスには、SQLをリクエストするメソッドが2種類あります。先程言った2つになります。

SQL文を送るメソッド「prepare」

まずはprepareです。

prepareのメリット・デメリット
  • セキュリティが高い。
  • 手間がかかる。

特徴はセキュリティ対策になる。リクエストするSQL文と、変化する値を別々にDBに送信するからです。

メールで添付ファイルを送信し、別のメールでパスワードを添付する場合があると思いますが、同じイメージです。

prepareの工程は下記です。

  1. SQL本文を決める(値が変化する)・・・メールで言う添付ファイル
  2. 変化する値を決める ・・・メールで言うパスワード
  3. 実行する ・・・メール送信

別々に送信するので、少し手間とリソースがかかります。

リソースとは資源。ここではPCのCPUやメモリ、通信の帯域の事です。

基本的に値が変化する場合は、こちらを使用しましょう。

prepareの基本構文を書く

$変数 = PDOから作成したインスタンスを格納した変数->prepare("SQL文");
$変数->bindValue(id,'変化する値',PDO::データ型);
$変数->execute();

SQL文を決めます。ここでは下記の4つから操作します。

今回は抽出する「select」を使用します。データベースのカラム「name」の値を変更して使いまわしします。

SQLのselect構文の詳細は、下記の記事を参照してください。

変更する値は場所だけ確保しておきます。確保する領域を「プレースホルダー」と言います。

プレース ホルダーは2種類あります。「?」と「:名前」です。

SQL文を入れた今回のコードは下記です。どちらでも構いません。

プレース ホルダー「?」の場合

$stmt = $db->prepare("select score from users where name=?");

プレース ホルダー「:名前」の場合

$stmt = $db->prepare("select score from users where name=:ユーザー");

usersテーブルからカラム「score」の値を取得します。カラム「name」が変化する値で、プレース ホルダーを使用しています。

インスタンス$dbのprepareメソッドで、SQL文を送る構文を変数「$stmt」に格納しました。

prepareのプレースホルダーを埋める構文

次にプレースホルダ―の値を埋めます。ここでは2つのメソッドがあります。

  1. bindValue
  2. bindParam

違い① bindValueで与える値は、直接値を指定しても、変数を使用してもOKです。bindParamで与える値は変数のみです。

違い② bindParamで実行する時にINT(数値型)を指定しても文字列になる。

違い③ bindValue もbindParamもexecuteで実行しますが、bindValue構文はその場で値が決まります。bindParamはexecuteする時に値が決まります。その前に変数の値が変われば、その値に変わるという事です。

prepareのプレースホルダーを埋めるbindValue構文

先程のSQLの「?」の部分の値を決めます。構文は下記です。

$stmt->bindValue(id,'値',オプション);

再程の変数$stmtから->bindValueメソッドを呼び出しています。()の中身は下記です。

オプションはデータ型を指定できます。種類は下記です。

文字列型と数値型が、ほとんどだと思います。

以上を踏まえて、今回のコードは下記になりました。

プレース ホルダー「?」の場合

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

プレース ホルダー「:名前」の場合

$stmt->bindValue(':ユーザー','user_1',PDO::PARAM_STR);

プレース ホルダー「?」の場合 「?」が一つしかないので、idは1

プレース ホルダー「:名前」の場合 、 一つしかないので、当然:ユーザーになります。

今回はカラム「name」が「user_1」の値の取得

「user_1」なので文字列型を指定して、バインドしようと思います。

これで、SQLの構文と、変化する値が決まりました。

prepareのプレースホルダーを埋めるbindParam構文

基本的にbindValueと同じです。違いの一つは下記でした。

違い① bindValueで与える値は、直接値を指定しても、変数を使用してもOKです。bindParamで与える値は変数のみです。

違い①bindParamの場合、値は変数のみ

プレース ホルダー「?」の場合

$user = 'user_1'
$stmt->bindParam(1,$user,PDO::PARAM_STR);

プレース ホルダー「:名前」の場合

$user = 'user_1'
$stmt->bindParam(':ユーザー',$user,PDO::PARAM_STR);

bindParamの場合、値の箇所を変数にしないとエラーとなります。変数$userにしました。

SQLリクエストをexecuteで実行する

最後はDBにリクエストしなければ、値を抽出する事は出来ません。

prepareでSQLリクエストするには、下記構文が必要です。

$変数->execute();

executeは実行するメソッドです。これでprepareでSQL文をリクエスト可能です。

prepareでSQLするコードをまとめると、下記になりました。

bindValueでSQL文を実行する

プレース ホルダー「?」の場合

 $stmt = $db->prepare("select score from users where name=?");
 $stmt->bindValue(1,'user_1',PDO::PARAM_STR);
 $stmt->execute();

プレース ホルダー「:名前」の場合

 $stmt = $db->prepare("select score from users where name=:ユーザー");
 $stmt->bindValue(':ユーザー','user_1',PDO::PARAM_STR);
 $stmt->execute();

bindParamでSQL文を実行する

プレース ホルダー「?」の場合

$user = 'user_1'
$stmt = $db->prepare("select score from users where name=?");
$stmt->bindParam(1,$user,PDO::PARAM_STR);
$stmt->execute();

プレース ホルダー「:名前」の場合

$user = 'user_1' 
$stmt = $db->prepare("select score from users where name=:ユーザー");
$stmt->bindParam(':ユーザー',$user,PDO::PARAM_STR);
$stmt->execute();

基本的にbindValueと同じです。残りの違いは下記でした。

違い② bindParamで実行する時にINT(数値型)を指定しても文字列になる。

違い②により、すべて文字列になります。今回は「user_1」で文字列でしたが、INT型の数値だったとしたらexecuteの箇所で文字列型になります。

基本的にbindValueと同じです。残りの違いは下記でした。

違い③ bindValue もbindParamもexecuteで実行しますが、bindValue構文はその場で値が決まります。bindParamはexecuteする時に値が決まります。その前に変数の値が変われば、その値に変わるという事です。

違い③により、構文が下記だった場合

$user = 'user_1' 
$stmt = $db->prepare("select score from users where name=:ユーザー");
$stmt->bindParam(':ユーザー',$user,PDO::PARAM_STR);
$user = 'user_2'
$stmt->execute();

executeの箇所に行くまでに$user変数の値が変わっています。bindValueであれば「user_1」、bindParamであれば「user_2」がクエリされます。

値が変化する場合は、prepareを使用しましょう。

bindParamを使用する時は、下記に注意しましょう。

bindParam注意点
  • 値が文字列になる
  • 途中で変数に値が入ると、SQLも変化する

SQL文を送るメソッド「query」

次はqueryです。queryは値が変化しない場合に使用します。

SQLと値を分ける事もなく、query自体実行まで行います。

prepareの工程は下記でした。

  1. SQL本文を決める(値が変化する)・・・メールで言う添付ファイル
  2. 変化する値を決める ・・・メールで言うパスワード
  3. 実行する ・・・メール送信

queryは上記3つの工程を、1つで行います。

queryのメリット・デメリット
  • 手間がかからず、簡潔に完了する

ではqueryの構文は下記になります。

$stmt = $db->query("select score from users where name=user_1");

値が変更しない、確定している場合にはqueryを使用しましょう。

PDOのprepareとqueryでSQL文を変数に格納するのまとめ

prepareのまとめ

prepareでSQL文を変数に格納する時は、値が変化する時

プレース ホルダー「?」の場合

 $stmt = $db->prepare("select score from users where name=?");
 $stmt->bindValue(1,'user_1',PDO::PARAM_STR);
 $stmt->execute();

プレース ホルダー「:名前」の場合

 $stmt = $db->prepare("select score from users where name=:ユーザー");
 $stmt->bindValue(':ユーザー','user_1',PDO::PARAM_STR);
 $stmt->execute();

変化する場所は「?」か「:名前」で場所を確保、場所を「 プレース ホルダー」と呼ぶ。

変化する値は「bindValue」か「bindParam」で指定する。

bindParamの注意点は下記

bindParam注意点
  • 値は変数で指定しないとエラーになる
  • 値が文字列になる
  • 途中で変数に値が入ると、SQLも変化する

複数ある場合は、「?」の場合番号で、「:名前」の場合は名前で指定する。

データ型も指定できる。方は下記などあるが、STR(文字列)かINT(数値)がほとんど

prepareは実行も必要。実行はexecuteで行う。

queryのまとめ

queryでSQL文を変数に格納する時は、値が変化しない時

$stmt = $db->query("select score from users where name=user_1");

この1行のみで完了。理由はbind不要(値が変化しない為)、実行もしてくれる為

これからもっとPHPのスキルを上げる為には

長くなりましたが、終わりです。難しいですが頑張って習得してください

短期間にスキルを上げて、転職したい、フリーランスになりたい場合はプログラミングスクールで学習するべきです。

劇的にプログラミングスキルが上がります、現役エンジニアから業界の事も聞けるのでオススメです。

PDOのprepareとqueryでSQL文を変数に格納した後は

格納した後はその値を取得したりも可能です。fetchやfetchAllを使用します。

詳しい事は下記の「PDOのfetchやfetchAllで値を抽出する」の記事をご覧ください

モバイルバージョンを終了