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

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

ただいまの
回答率

87.59%

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

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 11K+

score 15

前提・実現したいこと

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • キャンセル

  • m.ts10806

    2019/02/27 09:58

    バッククォートの件は予約語との識別とかも関係ありますね。
    https://dev.mysql.com/doc/refman/5.6/ja/reserved-words.html

    キャンセル

  • yuna3

    2019/02/27 19:46

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

    キャンセル

回答 1

checkベストアンサー

+7

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

ですが、

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

  1. キャスト(array)が邪魔
  2. 配列の添え字で使うIDとidは別物。データベースの設定と合ってる?

1.キャスト(array)が邪魔について

PDO::queryの返却値は「PDOStatement オブジェクト」OR「false」です。
つまり、返却値を確認してfalseでなければ、一応、queryは無事届けられたと思って良いです。
try-catchを随所に書かれていますが、それはプログラムが必ず成功するわけではないという前提で書かれているもののはずです。
で、あれば、そのqueryも必ず成功するわけではないという前提で対応しましょう。

if(!$stmt){
  die('失敗');
}
//成功したときの処理

もちろん、デバッグのために$stmtが何をもっているか確認するのは必須です。

var_dump($stmt);
if(!$stmt){
  die('失敗');
}
//成功したときの処理

※確認できたらいったん行頭に//をつけてコメントアウトしておくと良いです。

これで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の前でこうしてみましょう。

var_dump((array)$stmt);

結果は下記のようになっていませんか?
array(1) { ["queryString"]=>  string(XX) "SELECT ID FROM TB_LIST" }

PDO::queryで折角取得できたPDOStatementがなくなってしまっています。
つまり、SELECT文の実行結果は「結果セット」つまり、データが入っているとイコールなので、そこがなくなってしまうと
実行結果もなくなってしまうということになります。

実行結果をそのまま素直にループさせれば良いです。

    foreach ($stmt as $row) {
        // 出力
        echo $row['ID'];
    }


キャストを含めたコーディングで注意すべき点は下記のような記事が参考になります。

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.を全て対応した後でも想定通りの結果が出ない場合はここまでやってみてください。
配列の添え字のキーを間違えていないか?大文字と小文字は別物です。

$hoge["a"] = "hello";
echo $hoge["d"]; // Notice: Undefined index: A
echo $hoge["A"]; // Notice: Undefined index: A
echo $hoge["a"]; // Hello

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

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

以上。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/22 19:35

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

    キャンセル

  • 2019/02/27 00:32

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

    キャンセル

  • 2019/02/27 07:20

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

    キャンセル

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

  • ただいまの回答率 87.59%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る