DBに接続する際には下記のような記事が参考になります。
ですが、
解決したいだけでしたら確認する点は二点です。
- キャスト(array)が邪魔
- 配列の添え字で使うIDとidは別物。データベースの設定と合ってる?
1.キャスト(array)が邪魔について
PDO::queryの返却値は「PDOStatement オブジェクト」OR「false」です。
つまり、返却値を確認してfalseでなければ、一応、queryは無事届けられたと思って良いです。
try-catchを随所に書かれていますが、それはプログラムが必ず成功するわけではないという前提で書かれているもののはずです。
で、あれば、そのqueryも必ず成功するわけではないという前提で対応しましょう。
php
1if(!$stmt){
2 die('失敗');
3}
4//成功したときの処理
もちろん、デバッグのために$stmtが何をもっているか確認するのは必須です。
php
1var_dump($stmt);
2if(!$stmt){
3 die('失敗');
4}
5//成功したときの処理
※確認できたらいったん行頭に//をつけてコメントアウトしておくと良いです。
これでvar_dump()の結果が
object(PDOStatement)#3 (1) { ["queryString"]=> string(XX) "SELECT ID FROM TB_LIST" }
のように返ってきていたら成功しています。
もし、bool(false)
とだけ出ていたら失敗しています。
ここで1点アドバイス。
今のコーディング内容ではPDOExceptionをちゃんと拾うようにできていません。
new PDO()
する際に幾つか引数をつけて実行していると思いますが
PDOの引数、今のところは$dsn,$username,$passwordまでしか入れてませんよね?
その次の$optionに注目してください。
ドライバ固有の接続オプションを指定するキー=> 値の配列。
ここで色々なOPTIONを指定することができますが、その中にATTR_ERRMODEというのがあります。(属性の説明)
ここでPDO::ERRMODE_EXCEPTIONを指定することできちんとExceptionを拾うようになります。
最初に提示したQiitaの参考記事では下記のように$optionsを指定していますね。
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false,
]
上記をPDO()接続時の引数に指定した上でもう一度実行してみてください。
そこでエラーSQLSTATE[・・・・
のようなエラーメッセージが出てきたらその先のエラーコードとエラー理由を確認しましょう。
参考:エラーメッセージの読み方と対処, 検索や質問の原則
出ていないのでしたらようやく「キャスト(array)が邪魔」の対応ができます。
出ていない=queryはきちんと届けられていて成功している わけですが
キャストをしてしまうことで変数の型が変わります。
foreachの前でこうしてみましょう。
php
1var_dump((array)$stmt);
結果は下記のようになっていませんか?
array(1) { ["queryString"]=> string(XX) "SELECT ID FROM TB_LIST" }
PDO::queryで折角取得できたPDOStatementがなくなってしまっています。
つまり、SELECT文の実行結果は「結果セット」つまり、データが入っているとイコールなので、そこがなくなってしまうと
実行結果もなくなってしまうということになります。
実行結果をそのまま素直にループさせれば良いです。
php
1 foreach ($stmt as $row) {
2 // 出力
3 echo $row['ID'];
4 }
キャストを含めたコーディングで注意すべき点は下記のような記事が参考になります。
foreach()には配列とオブジェクトのみ使えますが、
何が入っているか確かめていない配列を(array)でキャストすることによって
無理やりコードを正常化してしまっていることになります。
つまり、気づけたはずのエラーが気づけなくなるわけです。
これに限らずキャストが必要な場面はほとんどありません。
キャストするくらいなら変数が想定の情報を持ってきているかを確認した上で実行するように組んでください。
2.配列の添え字で使うIDとidは別物。データベースの設定と合ってる? について
これに加えてもう1つ確認すべき点があります。
一応(array)キャストをすることで下記のような配列ができるのでforeachはできるはず。
array(1) { ["queryString"]=> string(XX) "SELECT ID FROM TB_LIST" }
コードでは$row['ID']
を参照しようとしていますが、そのようなデータありません。
連想配列そのまま回しているので$rowだけでSELECT ID FROM TB_LIST
が取れるはず。
PHPにおいて、存在しないキーを参照しようとするとWarning: Illegal string offset '指定名'
またはNotice: Undefined index
のようなエラーが出ます。
※きちんとケースはありますが、どちらかが出てたら参照が間違っているという理解でいたらいいです
おそらく質問者さんの実行環境ではエラー表示が制御されているのではないでしょうか。
学習段階、開発途中段階のコードでは何が起きるか分からないので、全てのレベルのエラー表示をするようにしておくことを強くすすめます。
1.を全て対応した後でも想定通りの結果が出ない場合はここまでやってみてください。
配列の添え字のキーを間違えていないか?大文字と小文字は別物です。
php
1$hoge["a"] = "hello";
2echo $hoge["d"]; // Notice: Undefined index: A
3echo $hoge["A"]; // Notice: Undefined index: A
4echo $hoge["a"]; // Hello
5
以下、今後を見据えた場合の蛇足。
- データを出力するときはHTMLエスケープをしよう。
なぜそうすべきかというのはXSSとかで調べると良いです。
0. 今後、もしかしたら検索条件などを指定してデータを取得する機会があるかもしれませんが、そのときはSQLのエスケープは必ず行おう。PDO::queryよりもPDO::prepareで「プリペアドステートメント」をセットしてからのbindValueがおすすめです。
なぜそうすべきかはSQLインジェクションとかで調べると良いです。
以上。