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

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

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

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

Q&A

解決済

2回答

2190閲覧

PHP 練習で掲示板を作成しているのですが、mySQLから投稿データを表示出来ません。

yuuki_kun

総合スコア1

PHP

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

0グッド

0クリップ

投稿2020/07/10 12:34

編集2020/07/11 00:21

前提・実現したいこと

macOS
Xserver
phpmyAdmin(MySQL5.7)
PHP7.3.16

掲示板を作成してます。
■確認済み
MySQLへ投稿内容のデーブル登録までは確認。

データベースのデータを取得して表示したいのですが、
下記のエラーがブラウザに出てしまいます。

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

PHP

1 2 if ($res) { 3 $message_array = $res->fetch_all(MYSQLI_ASSOC);

エラーメッセージ

Fatal error: Uncaught Error: Call to undefined method mysqli_result::fetch_all() in /home/public_html/index.php:96 Stack trace: #0 {main} thrown in /home//public_html/index.php on line 96 ### 該当のソースコード

PHP

1//データベースの接続情報(一応こちらに掲載するにあたり削除してます) 2define('DB_HOST', ''); 3define('DB_USER', ''); 4define('DB_PASS', ''); 5define('DB_NAME', ''); 6 7 8 9// タイムゾーン設定 10date_default_timezone_set('Asia/Tokyo'); 11 12//変数の初期化 13$now_date = null; 14$data = null; 15$file_handle = null; 16$split_data = null; 17$message = array(); 18$message_array = array(); 19$success_message = null; 20$error_message = array(); 21$clean = array(); 22 23session_start(); 24 25if (!empty($_POST['btn_submit'])) { 26 27 //表示名の入力チェックは匿名送信可のためコードなしでいく。 28 //サニタイズ機能(不正入力防止)機能は実装。 29 //改行を削除する機能。 30 $clean['view_name'] = htmlspecialchars($_POST['view_name'], ENT_QUOTES); 31 $clean['view_name'] = preg_replace('/\r\n|\n|\r/', '', $clean['view_name']); 32 33 //セッションに表示名を保存 34 $_SESSION['view_name'] = $clean['view_name']; 35 36 //メッセージの入力チェック 37 //サニタイズと改行をbr要素へ置き換えるコード実装。 38 if (empty($_POST['message'])) { 39 $error_message[] = 'ひと言メッセージを入力してください。'; 40 } else { 41 $clean['message'] = htmlspecialchars($_POST['message'], ENT_QUOTES); 42 $clean['message'] = preg_replace('/\r\n|\n|\r/', '<br>', $clean['message']); 43 } 44 45 if (empty($error_message)) { 46 47 //データベースに接続 48 $mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME); 49 50 //接続エラーの確認 51 if ($mysqli->connect_errno) { 52 $error_message[] = '書き込みに失敗しました。エラー番号 ' . $mysqli->connect_errno . ' : ' . $mysqli->connect_error; 53 } else { 54 55 //文字コード設定 56 $mysqli->set_charset('utf8'); 57 58 //書き込み日時を取得 59 $now_date = date("Y-m-d H:i:s"); 60 61 //データを登録するSQL作成 62 $sql = "INSERT INTO message (view_name,message,post_date) 63 VALUES ( '$clean[view_name]','$clean[message]','$now_date')"; 64 65 //データを登録 66 $res = $mysqli->query($sql); 67 68 if ($res) { 69 $success_message = 'メッセージを書き込みました。'; 70 } else { 71 $error_message[] = '書き込みに失敗しました。'; 72 } 73 74 //データベースの接続を閉じる 75 $mysqli->close(); 76 } 77 } 78} 79 80 81//データベースに接続 82$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME); 83 84//接続エラーの確認 85if ($mysqli->connect_errno) { 86 $error_message[] = 'データの読み込みに失敗しました。エラー番号 ' . $mysqli->connect_errno . ' : ' . $mysqli->connect_error; 87} else { 88 89 //ここにデータを取得する処理が入る 90 $sql = "SELECT view_name,message,post_date FROM message ORDER BY post_date DESC"; 91 $res = $mysqli->query($sql); 92 93 if ($res) { 94 $message_array = $res->fetch_all(MYSQLI_ASSOC); 95 } 96 97 $mysqli->close(); 98} 99 100?> 101 102<!DOCTYPE html> 103<html lang="ja"> 104 105<head> 106 <meta charset="utf-8"> 107 <title>ひと言掲示板</title> 108 <style> 109 110 body { 111 112 } 113 114 115 /*------------------------------ 116Common Style 117------------------------------*/ 118 body { 119 120<body> 121 <h1>ひと言掲示板</h1> 122 123 <!-- ここにメッセージがある場合に「メッセージを書き込みました。」を表記させるコード --> 124 <?php if (!empty($success_message)) : ?> 125 <p class="success_message"><?php echo $success_message; ?></p> 126 <?php endif; ?> 127 128 <!-- $error_messageに値が入っていたらエラーメッセージを表示 --> 129 <?php if (!empty($error_message)) : ?> 130 <ul class="error_message"> 131 <?php foreach ($error_message as $value) : ?> 132 <li><?php echo $value; ?></li> 133 <?php endforeach; ?> 134 </ul> 135 <?php endif; ?> 136 137 <!-- ここにメッセージの入力フォームを設置 --> 138 <form method="post"> 139 <div> 140 <label for="view_name">表示名</label> 141 <input id="view_name" type="text" name="view_name" value="<?php if (!empty($_SESSION['view_name'])) { 142 echo $_SESSION['view_name']; 143 } ?>"> 144 </div> 145 <div> 146 <label for="message">ひと言メッセージ</label> 147 <textarea id="message" name="message"></textarea> 148 </div> 149 <input type="submit" name="btn_submit" value="書き込む"> 150 </form> 151 <hr> 152 <section> 153 <!-- ここに投稿されたメッセージを表示 --> 154 <?php if (!empty($message_array)) : ?> 155 <?php foreach ($message_array as $value) : ?> 156 <article> 157 <div class="info"> 158 <h2><?php echo $value['view_name']; ?></h2> 159 <time><?php echo date('Y年m月d日 H:i', strtotime($value['post_date'])); ?></time> 160 </div> 161 <p><?php echo $value['message']; ?></p> 162 </article> 163 <?php endforeach; ?> 164 <?php endif; ?> 165 </section> 166</body> 167 168</html>

試したこと

いくつかのサイトを参考に、fetchの行のコードを変えてみたり、
PDOで書いて試してみたりしましたが、知識が足りないのもあり、成功しませんでした。

宜しくお願いします。

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

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

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

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

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

m.ts10806

2020/07/10 12:36

「初心者アイコン」を質問に付けられるのでそちらを利用してください。 タイトルや本文にわざわざ書く必要はありません。 コードやエラーはマークダウンのcode機能を利用してご提示ください。 https://teratail.com/questions/238564
m.ts10806

2020/07/10 12:38

Reset Style  ・・・とかって問題再現するのに必要でしょうか? 全体把握しないまま全部ポイッと投げて「あとよろしく」と言ってるようにも見えます。丸投げ感が出るとアドバイスも得られにくくなります。 可能なら、「現象が再現する最小構成のコード」を組み直して提示してください。 >https://teratail.com/help/question-tips#questionTips3-5-1 >最も良いのは、現象を再現するためのミニマムなプログラムを改めて作ることです。そうすれば、貴方自身が現象と問題をより良く理解することにもつながるからです。
m.ts10806

2020/07/10 12:53

念のため。質問は編集できますので適宜ご対応ください。
miyabi_takatsuk

2020/07/10 13:35

余計なお節介ではありますが、 これは公開ディレクトリのファイルでしょうか? そこにDB接続情報書いちゃうのはかなり危険かと・・・。
yuuki_kun

2020/07/11 00:08

m.ts10806さん アドバイスありがとうございます。「現象が再現する最小構成コード」に修正します。 (※時間がかかると思いますが、調べながら、検証しながら挑戦していきたいと思います。) miyabi_takatsuk セキュリティに関するアドバイスありがとうございます。 まさに、xserverのpublic_htmlに入れておりました。 他の質問者さまの記事を読んで、勉強します。
guest

回答2

0

ベストアンサー

多分同じ問題なので、回答を参照してください

サーバー側の問題なので、fetch_all()を諦めてfetch_assoc()をループさせるなどの対応が必要です。

ただ、余程深刻な理由がない限りは、PDOで全部書くことをおすすめします。

それはそれとして、書かれているコードが教材のサンプル等であれば、致命的な点がいくつもあるので、これも余程深刻な理由がない限りは教材を~変更されることをおすすめします。

具体的には

PHP

1//サニタイズと改行をbr要素へ置き換えるコード実装。 2if (empty($_POST['message'])) { 3$error_message[] = 'ひと言メッセージを入力してください。'; 4} else { 5$clean['message'] = htmlspecialchars($_POST['message'], ENT_QUOTES); 6$clean['message'] = preg_replace('/\r\n|\n|\r/', '<br>', $clean['message']); 7}

これは2000年代に量産された間違ったセキュリティ対策の典型です。
今時こんなコードを書いていたら切られても止むを得ないと言わざるを得ない品質です。
参考:自己流のSQLインジェクション対策は危険

また、mysqli_系の関数は、WordPressや既存の歴史の長いOSSを触る人以外は新たに勉強するメリットはあんまりありません。(このソースの元サイトの主催者はWordPressを専門にしているので、mysqli系を使っているに過ぎないんだと思われます)

web上での教材だとprogateは、無料コースでもがんばればなんとかなりそうな品質だと思いますよ。
(教材を探すのは難しいのですが、教材のソースをteratailで検索してみて、出てくる質問と回答にこの回答の様なコメントがついていればちょっと怪しいかもと考えることをお勧めします)

投稿2020/07/10 13:24

編集2020/07/10 13:58
tanat

総合スコア18727

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

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

yuuki_kun

2020/07/11 00:30

アドバイスありがとうございます。 セキュリティのコードがあってるかどうかの判断もつかなかったので非常に勉強になります。 最新のコードを吸収していきたいと思います。 まだ勉強を始めたばかりですので、他の方がオススメして下さってる教材での学習に方向転換したいと思います。ありがとうございました。
guest

0

基本的なところだけ突っ込んでおきます(根本原因とは限りません)

  • シングルクォーテーションの中では変数展開できません

php

1$a = ["a"=>""]; 2echo '$a["a"]';
  • htmlspecialchars() などはHTML出力時に行うものであってDB保存時に行うものではありません。原則、そのまま保存してください。
  • SQLインジェクション対策がなされていないように見えます。PDO使わないにしても、mysqliの機能もあります。

ただ、mysqliでもPDOと同じようにpreparebindexecuteの流れが望ましいです。

  • 例外処理も必要です。
  • INSERTして最新データをSELECTならいちいちcloseしなくてもいいんじゃないかな・・・

投稿2020/07/10 12:52

m.ts10806

総合スコア80875

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問