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

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

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

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

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

バインド

バインドは、一定の方法で複数の事柄が関連付けられている状態を呼びます。また、そのような関連付けを実行する機能自体を指す事もあります。

Q&A

解決済

3回答

1933閲覧

phpのPDOバインドで空の出力が出てしまいます。

heypo

総合スコア3

PDO

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

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

バインド

バインドは、一定の方法で複数の事柄が関連付けられている状態を呼びます。また、そのような関連付けを実行する機能自体を指す事もあります。

0グッド

0クリップ

投稿2020/09/11 14:12

編集2020/09/12 01:53

前提・実現したいこと

PHPでサービスを作ってます。
別のページでは動いているPDOの命令が動きません。
バインドに問題があると思いますが、いろいろ試しましたがわかりませんでした。
よろしくお願いします。

環境 PHP Version 7.4.1    mamp使用  phpMyAdmin バージョン情報: 4.9.3

発生している問題・エラーメッセージ

出力が空で返ってきます。

PHP

1array(0) { }

該当のソースコード

PHP

1<?php 2$post_choose_offer = $_POST['choose_offer']; 3 4echo $post_choose_offer; 5 6□□□□□□□□□□ ここでは 5f5383012c89e が返ってきています。 □□□□□□□□□□ 7 8try { 9 10   // データベースに接続 11 require_once('../〇〇〇〇/db_connection.php'); 12 13   // sql文を作成 14   // POSTで渡されたoffer_codeがデータベース内に存在するかを検索するsql文 15 $prepare = $pdo->prepare('SELECT * FROM offer WHERE offer_code = :offer_code'); 16 17 18 19   // sql文のバインド処理 20   // [ :offer_code ]を$post_choose_offerでバインド 21 $prepare->bindValue(':offer_code', (string) $post_choose_offer, PDO::PARAM_STR); 22 23   // sql文実行 24 $prepare->execute(); 25 26   // データベースからの戻り値を受け取り、変数に格納 27 $offer_data = $prepare->fetchAll(PDO::FETCH_ASSOC); 28 29 30 31} catch (PDOException $e) { 32 echo '接続エラー' . $e->getMessage() . "\n"; 33 exit(); 34} 35 36 37 echo ' offer_data <br> '; 38 var_dump($offer_data); 39□□□□□□□□□□ ここでarray(0) { }が返ってきています。 □□□□□□□□□□ 40

試したこと

以下のコードで、バインドせずに直接文字列を入れると、DBから欲しい情報が返ってきます。

PHP

1$prepare = $pdo->prepare('SELECT * FROM offer WHERE offer_code = "5f5383012c89e"');

念のためにPOSTを受けた直後にキャストもしましたが、変化なし。 

PHP

1(string)$post_choose_offer

fetchAll を fetch でも変化なし。

###追記

var_dumpで出力した結果

PHP

1var_dump($post_choose_offer);

HTML

1string(14) " 5f5383012c89e"

変数に文字列を入れてバインドした結果。

PHP

1$post_choose_offer = "5f5383012c89e";

こちらで欲しい情報が取れました。
ですので、バインドの問題では無いのかな?

PHP

1$prepare->PDOStatement::debugDumpParams();

こちらで出力すると

HTML

1SQL: [54] SELECT * FROM offer WHERE offer_code = :offer_code 2Params: 1 3Key: Name: [11] :offer_code 4paramno=0 5name=[11] ":offer_code" 6is_param=1 7param_type=2 8

出力の内容をまだ理解して無いので、調べている途中です。

むやみにキャストしてはいけないとご意見を頂いたので、以下に変更しました。
ありがとうございます。

PHP

1$prepare->bindValue(':offer_code', $post_choose_offer, PDO::PARAM_STR);

###解決

form側でスペースが混入していたのに気付きませんでした。
アホでした。

HTML

1string(14) " 5f5383012c89e"

回答を頂いたみなさま、大変ありがとうございました。

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

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

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

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

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

m.ts10806

2020/09/11 20:48

コードはマークダウンのcode機能を利用してご提示ください
heypo

2020/09/12 00:34

大変失礼しました。 ご指摘ありがとうございます。 使い方にまだ慣れていないもので申し訳ございません。 マークダウン記法に変更いたしました。
guest

回答3

0

ベストアンサー

まずは、
PDOStatement::debugDumpParamsを使用して、狙った値がバインド出来ているか確認してみましょう。

また、PDOの接続部分でどの様なオプションを指定しているか不明ですが
必ず
PHP・PDO、SQL実行時のエラーをExceptionで捕捉する
の様な形でSQLに文法エラーがあった時は例外がthrowされるように設定してください。

こちらで試した限りだとコードに問題は無い様に見えるので
前述の
PDOStatement::debugDumpParamsに合わせて

PHP

1$post_choose_offer = $_POST['choose_offer']; 2 3echo $post_choose_offer;

PHP

1$post_choose_offer = $_POST['choose_offer']; 2var_dump($post_choose_offer);

として、値が欠けたりしていないかを確認してみてください。
おそらく現状でも

PHP

1$post_choose_offer = "5f5383012c89e";

とした場合は動作すると思います。

投稿2020/09/11 14:55

編集2020/09/11 15:10
tanat

総合スコア18713

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

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

heypo

2020/09/12 01:05

返信ありがとうございます。 ```HTML出力 var_dump post_choose_offer string(14) " 5f5383012c89e" ``` POSTで渡しているのはこの情報だけですので、問題なさそうです。 ```PHP $post_choose_offer = "5f5383012c89e"; ``` こちらで欲しい情報が出力されました。 ```PHP $prepare->debugDumpParams(); ``` で出力した結果 ```HTML出力 SQL: [54] SELECT * FROM offer WHERE offer_code = :offer_code Params: 1 Key: Name: [11] :offer_code paramno=0 name=[11] ":offer_code" is_param=1 param_type=2 ``` 出力された内容をまだ理解できていないので、調べている途中です。
tanat

2020/09/12 01:17

string(14) " 5f5383012c89e" 頭にスペースが入ってませんか?
heypo

2020/09/12 01:39

解決しました! ありがとうございます。 アホなミスで申し訳ございませんでした。 HTML form 側の select option value で変数をforeachで回してたりして複雑になっていたので、見落としていました。 大変助かりました。 本当にありがとうございました。
tanat

2020/09/12 02:28

解決してよかったです。 var_dumpの良いところは文字数や型も表示してくれるところですね。 切り分けも含めた作りの定石としては、POST値をバリデーションする(今回のケースだと文字数やスペースのチェックして、問題があればDBに渡す前にエラーにする)事なのでその辺りも調べてみることをおすすめします
heypo

2020/09/13 12:44

ありがとうございます。 配列はvar_dumpで出して、変数はechoで出す。 なんかそんなクセがついていました。 大変参考になりました。
guest

0

まずはSELECT * FROM offer WHERE offer_code = '5f5383012c89e'
で想定のデータがとってこれるかどうかから。
※ダブルクォーテーションはMySQLだけだと思ってください。シングルクォーテーションで覚えた方が良いです。

これはPHPからではなくMySQLに対して直接実行してください。
これに限らずアプリケーションから実行する前に、想定の結果を得られるSQLを先に作ってください。
でないと「バインドに問題がある」という根拠になりません。
問題切り分けのために「どこまで正しく動くか」確認するのは必須です。
※SQLに関しては製造時ではなく設計時に形を作っておくことの方が多いです

あと、安易なキャストはバグの元です。
初心者を戒めるPHP#安易にキャストするな
echo $post_choose_offer;で確認できているなら、そのまま渡すべきです。

$prepare->bindValue(':offer_code', (string) $post_choose_offer, PDO::PARAM_STR); ↓ $prepare->bindValue(':offer_code', $post_choose_offer, PDO::PARAM_STR);

キャストしなくともPDO::PARAM_STRできちんと文字列として認識してくれますし、文字列として認識されるかどうか気になるのでしたらSQLに突っ込む前にバリデーションで弾くべきです。
想定する値があるなら尚更です。キャストで対応する案件ではありません。

投稿2020/09/12 00:31

m.ts10806

総合スコア80850

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

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

heypo

2020/09/12 01:29

返信ありがとうございます。 質問に追記を入れました。 キャストはクセでやってました。 ご指摘ありがとうございます。
heypo

2020/09/12 01:42

解決しました! form 側のミスでスペースが混入していました。 ありがとうございます。 アホなミスで申し訳ございませんでした。
m.ts10806

2020/09/12 03:03

誰か言ってますか?アホなミスって
heypo

2020/09/13 12:39

いえいえ、自責の念を込めて、です。
guest

0

php

1$prepare = $pdo->prepare('SELECT * FROM offer WHERE offer_code = :offer_code');

php

1$prepare = $pdo->prepare('SELECT * FROM offer WHERE offer_code = ":offer_code"');

で試してみましょう。

投稿2020/09/11 14:21

seastar3

総合スコア2285

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

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

heypo

2020/09/11 14:28

返信ありがとうございます。 ↓↓↓↓↓↓↓ offer_data ↓↓↓↓↓↓↓ array(0) { } 空で返ってきました。 残念です。
seastar3

2020/09/11 14:32

場当たり的な回答で申し訳ありません。 こういう場合は、echo デバッグで原因を切り分けていくのが確実でしょう。今後のプログラミングスキル向上のためにも、粘り強く取り組んで見ることを推奨します。
heypo

2020/09/11 14:55

いえいえ、ありがとうございます。 別のページで全く同じ仕組みが動いているので、迷宮に入っているところでした。 そのページからのコピペでも動かないので、別のところに原因があるのかもしれません。 がんばって解決してみます。
m.ts10806

2020/09/12 00:22 編集

>":offer_code" これだとバインド結果 "'abcd'" のようになるのでは・・
heypo

2020/09/12 01:42

解決しました! form 側のミスでスペースが混入していました。 ありがとうございます。 アホなミスで申し訳ございませんでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問