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

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

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

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

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

Q&A

解決済

1回答

21333閲覧

PHPでDBから取得した値を、画面上に表示したいです。

yuna3

総合スコア15

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

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

0グッド

1クリップ

投稿2019/02/21 18:02

編集2019/02/22 09:35

前提・実現したいこと

PHPでDBから取得した値を、画面上に表示したいです。

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

phpを使い、DBから値を取得し、画面上に表示したいのですが、表示できず困っています。 DBには接続できており、エラーは出ていません。 DB内には2件レコードが入っているため、その2件が出力される想定なのですが 全く表示されません…。 どこか違うデータベースに接続してしまっているのでしょうか…?

該当のソースコード

<?php //データベース接続情報 $user = "ユーザID"; $password = "パスワード"; $dsn = 'mysql:host=localhost;dbname=test;charset=utf8'; //データベース接続処理 try{ $connect = new PDO($dsn, $user, $password); $connect->query("set names utf8"); }catch (PDOException $e){ echo 'データベースにアクセスできません!' . $e->getMessage(); } echo '接続成功1'; try{ // SELECT文を変数に格納 $sql = 'SELECT ID FROM TB_LIST'; // SQLステートメントを実行し、結果を変数に格納 $stmt = $connect->query($sql); // foreach文で配列の中身を一行ずつ出力 foreach ((array)$stmt as $row) { // 出力 echo $row['ID']; } echo '接続成功2<br>'; }catch (PDOException $e) { die('DB接続エラー'. $e->getMessage()); } // 接続の解除 $connect = null; echo 'DB切断成功<br>'; ?>

試したこと

接続の有無等は確認し、下記のように表示されるようになっています。


接続成功1接続成功2
DB切断成功


ですが、肝心のDBから取得した値がとれず…。
phpMyAdmin自体をあまり理解できていないため
そこが原因なのか?とも考えているのですが
phpも初心者なので、原因の切り分けもできず…。
分からないことが分からない状態ですので、教えていただければと思います…。

補足情報(FW/ツールのバージョンなど)

DB・サーバーは、エックスサーバの無料のものを使用しています。

MySQLバージョン 5.0.95
WordPressバージョン: 5.0.3
PHPバージョン:PHP7.0.x

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

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

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

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

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

m.ts10806

2019/02/21 22:31 編集

WordPressはどこがどう関係しているのでしょうか?いずれにしても、タグは「MySQL」は追加された方が良いです。 あと、データは存在してますか?→失礼。2件あるんですね。
m.ts10806

2019/02/21 22:20

質問は編集できますので適宜ご対応ください
m.ts10806

2019/02/21 22:49

ちなみにlocalhostしている時点でphp実行しているサーバーに接続しにいきます。そこでdbnameも指定した状態でException拾っていないのであれば問題はないと思います。 エックスサーバは使ったことないですが、phpと同じサーバー内にDBがあるんですよね?サーバーのIPが同じであれば同じです。
kasa0

2019/02/22 00:07

$stmtはfalseになっていませんか? PHPのエラーログも確認しましょう。
m.ts10806

2019/02/22 01:39

補足なのでこちらに書きますが phpMyAdminはあくまでMySQLのデータを確認するためのツールなので、 本件とはほとんど関係なかったりします。
cerfweb

2019/02/22 11:28

今回のエラーには関係ないとは思いますが、SQL文のテーブル名とフィールド名は下記のようにバッククォートで括るようにしましょう。 SELECT `ID` FROM `TB_LIST` 特にフィールド名をバッククォートで括っていないと、サーバによってはエラーが返されることがあります。 また、このようにした方が処理速度も若干速くなるようです。
yuna3

2019/02/26 15:34

>kasa0さん $stmtがfalseになっておりました。 アドバイスいただき、ありがとうございました!
yuna3

2019/02/26 15:35

>cerfwebさん 全く知りませんでした…。アドバイスありがとうございます! バッククォートで括らせていただきました!
yuna3

2019/02/27 10:46

詳しくありがとうございます!! 読ませていただきます!
guest

回答1

0

ベストアンサー

DBに接続する際には下記のような記事が参考になります。

ですが、

解決したいだけでしたら確認する点は二点です。

  1. キャスト(array)が邪魔
  2. 配列の添え字で使う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

以下、今後を見据えた場合の蛇足。

  1. データを出力するときはHTMLエスケープをしよう。

なぜそうすべきかというのはXSSとかで調べると良いです。
0. 今後、もしかしたら検索条件などを指定してデータを取得する機会があるかもしれませんが、そのときはSQLのエスケープは必ず行おう。PDO::queryよりもPDO::prepareで「プリペアドステートメント」をセットしてからのbindValueがおすすめです。
なぜそうすべきかはSQLインジェクションとかで調べると良いです。

以上。

投稿2019/02/22 00:16

編集2019/02/22 02:31
m.ts10806

総合スコア80873

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

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

yuna3

2019/02/22 03:37

詳しく基礎からご回答いただき、本当にありがとうございます!! 教えていただいた内容を理解して書き換え、ご報告させていただきます!
m.ts10806

2019/02/22 03:49

ヒントになったようで何よりです。 が、まだ終わってないのでしたら解決済みを外していただけますか? もしかしたらこちらが想定した通りの理解までできない可能性もあるし、この質問は「DBからデータを取得したい」が要件ですので、その要件が満たせてようやく解決だと思います。
yuna3

2019/02/22 05:37

失礼しました! ベストアンサーに設定すると、解決済みになってしまうのですね…。 解決済みを外す方法を調べます、お待ち下さい。 要件が満たせてから解決済みにさせていただきます!
m.ts10806

2019/02/22 06:01

teratailでの質問は未経験なのでやり方を教えることはできないのですが、 「高評価」「低評価」の感じからたぶんボタン1つなのではないかなぁと思ってはいます。実際に外してもらったり、外されたりしたことはあるので。
yuna3

2019/02/22 10:31

パソコンから見たら、解決済みを外せました! お騒がせしました…。 教わったことをじっくり考えて修正します!
m.ts10806

2019/02/22 10:35

スマホだとレイアウト違ったり機能も非表示になったりしますしね。 私はスマホから観るときもよく「PC表示」の機能切り替えをしています。 もし、途中わからないところがあったら適宜聞いてください
yuna3

2019/02/26 15:32

返信遅くなり、申し訳ありません。 やっと解決することができました!! 原因は、データベースに指定したテーブルが無いことでした…。 ソースコード上で接続しているデータベースとは違うWordPressを見ていたらしく、 混乱してしまっていました…。 ご回答いただいたキャスト(array)部分等も修正し、正常に出力できました。 詳しいご回答、ありがとうございました!!
m.ts10806

2019/02/26 22:20

はい。必ず「準備したものを使う」ようにしてください。ホスト情報も含めてコピペすれば間違うことは基本はないと思いますし、本来スペルミスなどは悩むところではないのでロジックに集中できます。 解決されたようで何よりです
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.42%

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

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

質問する

関連した質問