質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PDO

PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

5386閲覧

PDOの bindValue と execute を実行したときのデータベースとのやり取りについて教えてください。

退会済みユーザー

退会済みユーザー

総合スコア0

PDO

PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2015/03/13 09:11

編集2015/03/14 12:31

お世話になります。
現在、プリペアドステートメントについて調べている初心者です。
プリペアドステートメントの概要については「安全なSQLの呼び出し方」を読んで何となく理解しております。
「静的プレースホルダ」を使ってデータの取得・表示をしたいと考えております。
オプションで「PDO::ATTR_EMULATE_PREPARES => false」は設定しております。
「静的プレースホルダ」を使った場合のウェブアプリケーションとデータベースとのやり取りは「安全なSQLの呼び出し方」の解説図のようになる認識でおります。

データの取得・表示するには prepare → bindValue → execute → fetch の順で可能かと思います。
それぞれのメソッドについては、下記の処理を行っていると認識しております。

1.prepare
文を実行する準備を行い、文オブジェクトを返す

2.bindValue
値をパラメータにバインドする

3.execute
プリペアドステートメントを実行する

【質問】
バインドした後にプリペアドステートメントを実行しても静的プレースホルダになるのでしょうか?
個人的にはバインドした後に実行したら動的プレースホルダと一緒なのでは?と疑問に思っております。
executeするときにprepareの文とbindValueの値をそれぞれ別々にデータベースに送っているのでしょうか?

ご存じの方いれば、ご教示ください。
よろしくお願いいたします。

【質問追記】※2015.03.13 19:11
質問がわからないとのご指摘を頂きました。
luckerさん ありがとうございます。
私が「バインド」や「プレイペアドステートメント」の意味を正しく理解していないのが原因かと思います。

それぞれの言葉を使わずに質問したいと思います。

下記のコードで動作するかと思います。

【手順1】prepare
$stmt = $pdo->prepare('SELECT name FROM fruit WHERE price=?')

【手順2】bindValue
$stmt->bindValue(1, 100);

【手順3】execute
$stmt->execute();

静的プレースホルダは「SELECT name FROM fruit WHERE price=?」と「1, 100」の命令文を別々にデータベースに送ってデータベース側で結合して実行しているとの認識でおります。

「手順3」では「SELECT name FROM fruit WHERE price=?」と「1, 100」の命令文を別々にデータベースに送っているのでしょうか?

【追記】※2015.03.13 20:33

※この質問は、luckerさんのお陰で解決済みです。

私の日本語力の無さが原因でした。
「安全なSQLの呼び出し方」に下記の説明があります。

パラメータ部分を示す記号「?」のことをプレースホルダと呼び、そこへ実際の値を割り当てることを「バインドする」と呼びます。

日本語力のない私は、「バインドする」=「値を埋め込む」と勘違いしました。

PHPマニュアルの「PDOStatement::bindValue」の説明には下記のようにバインドすると記述があります。

値をパラメータにバインドする

bindValueメソッドは値を埋め込む処理をしていると勘違いしたため、上記のような質問を致しました。
bindValueメソッドを記述したところでプレースホルダに値が埋め込まれて一つのSQL文になっているわけではないようです。
executeされることではじめてプリペアドステートメントが実行されます。
executeすることでprepareに記述したSQL文がデータベース側で構文解析され、その後に値を当てはめるようになるようです。
ありがとうございました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

おっしゃりたいことがよく分からないのですが、
値をバインドする前に、プリペアドステートメントを“実行”したら、
一体何がDBに格納されるんでしょうか?

PDO::prepare()のことをおっしゃっているのなら、
これはステートメントをプリペアしているだけで実行はしていないと思いますが。

投稿2015/03/13 09:44

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2015/03/13 10:02

質問がわかりづらく申し訳ございません。 私が「バインド」と「プリペアドステートメント」などの言葉を誤った認識で使っているかもしれません。 それぞれの言葉を使わずに質問したいと思います。 下記のコードで動作するかと思います。 【手順1】prepare $stmt = $pdo->prepare('SELECT name FROM fruit WHERE price=?') 【手順2】bindValue $stmt->bindValue(1, 100); 【手順3】execute $stmt->execute(); 静的プレースホルダは「SELECT name FROM fruit WHERE price=?」と「1, 100」の命令文を別々にデータベースに送ってデータベース側で結合して実行しているとの認識でおります。 「手順3」では「SELECT name FROM fruit WHERE price=?」と「1, 100」の命令文を別々にデータベースに送っているのでしょうか?
退会済みユーザー

退会済みユーザー

2015/03/13 10:12

疑問に持たれていること、なんとなくわかりました。 PDOでプリペアした場合、バインドした値はステートメントには埋め込まずに別に送信されてDB側で評価されるようです。 ですから、実際に実行されるSQL文をPDOやPDOStatementから取得することはできません。 bindもprepareもDBに対しての指示ではなく、あくまでPDOStatementオブジェクトに対する指示です。 ですから、バインドをプリペアより先に行っても、やはり静的プレースホルダとして動作しているようです。
退会済みユーザー

退会済みユーザー

2015/03/13 10:23

luckerさん 何度もご回答いただきありがとうございます。 私は「bindValue=値の埋め込み」と誤解していたため、手順2の時点で既に値が埋め込まれているのかなと勘違いしておりました。 埋め込みはせず別に送信されるんですね。 お陰様で理解できました。 ありがとうございました。
退会済みユーザー

退会済みユーザー

2015/03/13 10:27

そうですね。正直のところ、動的プレースホルダなどという言葉があるのがややこしいかと思います。同じ“プレースホルダ”という言葉を使っていますが、全く別物ですね。
退会済みユーザー

退会済みユーザー

2015/03/13 10:38

「安全なSQLの呼び出し方」を読んでも、静的プレースホルダと動的プレースホルダは別物と書いてありますし、SQLインジェクションにも係るみたいなので気をつけないといけませんね>< もっと勉強します。 ありがとうございました^^
退会済みユーザー

退会済みユーザー

2015/03/13 10:39

申し訳ありません、補足と言いますか、訂正といいますか、 PDO::ATTR_EMULATE_PREPARESがtrueの場合は、PHP側で埋め込みを行ってからDBに送信するようです。 これは、プリペアドステートメントをサポートしないDB用のエミュレーションをPHP側で行うためのようですね。 もちろん、いずれの場合でもbindParam実行時に値が埋め込まれるわけではないのですが、念のため訂正します。申し訳ありません。
退会済みユーザー

退会済みユーザー

2015/03/13 10:44

PHP5.2以上ではPDO::ATTR_EMULATE_PREPARESがtrueになっていると調べたら書いてあったので、質問にも記載していおりますが、falseに設定しております。 trueだと動的プレースホルダのような挙動になるという認識でおります。 細かいところまでご指摘いただきありがとうございます^^
退会済みユーザー

退会済みユーザー

2015/03/13 10:50

私はもう、DBアクセスはフレームワーク化してしまっているので、ほとんどこういったアクセスの部分のコードを書くことがなくなってしまい、少し知識があやふやでした。 私も勉強になりました。有難うございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問