🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
foreach

foreachは、List・Collection・Arrayといったデータ構造の各要素に対して繰り返し処理を実行するために扱われる、制御構造の構文です。

PHP

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

Q&A

解決済

1回答

657閲覧

message画面に遷移したときに、コメントしていないのに空のコメントが画面に出力しているエラー

m2B

総合スコア20

foreach

foreachは、List・Collection・Arrayといったデータ構造の各要素に対して繰り返し処理を実行するために扱われる、制御構造の構文です。

PHP

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

0グッド

0クリップ

投稿2019/09/24 17:11

前提・実現したいこと

(例)PHPでサービス開発をしています。
コメント機能を作っています。if文やforeach文でデータ取得と画面出力に困っています。

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

「メッセージ投稿はまだありません」と画面に出力したいのですが、メッセージを送信していていないのに、空のテキストが出力されている状態です。(エラーはLINEのメッセージで例えるとメッセージ送信したときの空の状態が吹き出しに出てる状態です)

該当のソースコード

// 共通変数・関数ファイルを読み込む require('function.php'); debug('「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「'); debug('「 連絡掲示板ページ」'); debug('「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「「'); debugLogStart(); //======================== // 画面処理 //======================== $parterUserId = ''; $parterUserInfo = ''; $myUserInfo = ''; $giftInfo = ''; $viewData = ''; $u_id = $_SESSION['user_id']; // 画面表示用データ取得 // ========================= // GETパラメータを取得 $m_id = (!empty($_GET['m_id'])) ? $_GET['m_id'] : ''; // $g_id = (!empty($_GET['g_id'])) ? $_GET['g_id'] : ''; // DBから掲示板とメッセージデータを取得 $viewData = getMsgAndBoards($m_id); debug('取得したDBデータ(連絡掲示板) :' . print_r($viewData, true)); // パラメータに不正な値が入っているかチェック if (empty($viewData)) { error_log('エラー発生 : 指定したページに不正な値が入りました。'); header('Location:mypage.php'); // マイページへ } // ギフト情報を取得 $giftInfo = getGiftOne($viewData[0]['gift_id']); debug('取得したDBデータ :' . print_r($giftInfo, true)); // ギフト情報が入っているかチェック if (empty($giftInfo)) { error_log('エラー発生 : ギフト情報を取得できませんでした。'); header('Location:mypage.php'); // マイページへ } // viewDataから相手のユーザーIDを取り出す $dealUserIds[] = $viewData[0]['sale_user']; $dealUserIds[] = $viewData[0]['buy_user']; if (($key = array_search($_SESSION['user_id'], $dealUserIds)) !== false) { unset($dealUserIds[$key]); } $parterUserId = array_shift($dealUserIds); debug('取得した相手のユーザーID :' . $parterUserId); // DBから取引相手のユーザー情報を取得 if (isset($parterUserId)) { $parterUserInfo = getUser($parterUserId); } // 相手のユーザー情報が取れたかチェック if (empty($parterUserInfo)) { error_log('エラー発生 : 相手のユーザー情報が取得出来ませんでした'); header('Location:mypage.php'); } // DBから自分のユーザー情報を取得 $myUserInfo = getUser($_SESSION['user_id']); debug('取得したユーザーデータ :' . print_r($myUserInfo, true)); // 自分のユーザー情報と相手のユーザー情報が取れたかチェック if (empty($myUserInfo) && empty($parterUserInfo)) { error_log('エラー発生 : 自分のユーザー情報または相手のユーザー情報が取得できませんでした。'); header('Location:mypage.php'); } // POST送信されていた場合 if (!empty($_POST)) { debug('POST送信があります。'); // ログイン認証 require('auth.php'); // バリデーションチェック $msg = (isset($_POST['msg'])) ? $_POST['msg'] : ''; // 最大文字数チェック validMaxLength($msg, 'msg', '1000'); // 未入力チェック validRequired($msg, 'msg'); if (empty($err_msg)) { debug('バリデーションOKです'); // 例外処理 try { // DBへ接続 $dbh = dbConnect(); // SQL文作成 $sql = 'INSERT INTO message ( board_id, send_date, to_user, from_user, msg, create_date) VALUES (:b_id, :send_date, :to_user, :from_user, :msg, :date)'; $data = array( ':b_id' => $m_id, ':send_date' => date('Y-m-d H:i:s'), ':to_user' => $parterUserId, ':from_user' => $_SESSION['user_id'], ':msg' => $msg, ':date' => date('Y-m-d H:i:s') ); // クエリ実行 $stmt = queryPost($dbh, $sql, $data); if ($stmt) { $_POST = array(); //POSTをクリア debug('連絡掲示板へ遷移します。'); header('Location: ' . $_SERVER['PHP_SELF'] . '?m_id=' . $m_id); // 自分自身に遷移する } } catch (Exception $e) { error_log('エラー発生 :' . $e->getMessage()); $err_msg['common'] = MSG07; } } } debug('画面表示処理終了 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'); ?> <?php $siteTitle = '連絡掲示板'; require('head.php'); ?> <body class="page-msg page-1colum"> <!-- header --> <?php require('header.php'); ?> <p id="js-show-msg" style="display:none;" class="msg-slide"> <?php echo getSessionFlash('msg_success'); ?> </p> <!-- メインコンテンツ --> <div id="contents" class="site-width"> <!-- Main --> <section id="main-message"> <div class="msg-info"> <div class="avatar-img"> <img src="<?php echo showImg(sanitize($parterUserInfo['pic'])); ?>" alt="" class="avatar"> </div> <div class="avatar-info"> <?php echo sanitize($parterUserInfo['username']) . ' ' . sanitize($parterUserInfo['age']) . '歳' ?> <br> 〒<?php echo wordwrap($parterUserInfo['zip'], 4, "-", true); ?><br> <?php echo sanitize($parterUserInfo['addr']); ?><br> TEL : <?php echo sanitize($parterUserInfo['tel']); ?> </div> <div class="product-info"> <div class="left"> 取引商品<br> <img src="<?php echo showImg(sanitize($giftInfo['pic1'])); ?>" alt="" height="70px" width="auto"> </div> <div class="right"> <?php echo sanitize($giftInfo['name']); ?><br> 取引金額: <span class="price">¥<?php echo number_format(sanitize($giftInfo['price'])); ?></span><br> 取引開始日: <?php echo date('Y/m/d', strtotime(sanitize($viewData[0]['create_date']))); ?> </div> </div> </div> <div class="area-bord" id="js-scroll-bottom"> <?php if (!empty($viewData)) { foreach ($viewData as $key => $val) { if (!empty($val['from_user']) && $val['from_user'] == $parterUserId) { ?> <div class="msg-cnt msg-left"> <div class="avatar"> <img src="<?php echo sanitize(showImg($parterUserInfo['pic'])); ?>" alt="avatar"> </div> <p class="msg-inrTxt"> <span class="triangle"></span> <?php echo sanitize($val['msg']); ?> </p> <div style="font-size:.5em;"><?php echo sanitize($val['send_date']); ?></div> </div> <?php } else { ?> <div class="msg-cnt msg-right"> <div class="avatar"> <img src="<?php echo sanitize(showImg($myUserInfo['pic'])); ?>" alt="avatar"> </div> <p class="msg-inrTxt"> <span class="triangle"></span> <?php echo sanitize($val['msg']); ?> </p> <div style="font-size:.5em; text-align:right"><?php echo sanitize($val['send_date']); ?></div> </div> <?php } } } else { ?> <p style="text-align:center line-height:20;">メッセージ投稿はまだありません</p> <?php } ?> </div> <div class="area-send-msg"> <form action="" method="post"> <textarea name="msg" id="" cols="30" rows="3"></textarea> <input type="submit" value="投稿する" class="btn btn-send"> </form> </div> </section> <script> window.addEventListener('DOMContentLoaded', function() { //scrollHeightは要素のスクロールビューの高さを取得するもの $('#js-scroll-bottom').animate({ scrollTop: $('#js-scroll-bottom')[0].scrollHeight }, 'fast'); }); </script> </div> <!-- footer --> <?php require('footer.php'); ?>

試したこと

if文で条件分岐してforeach文で回しています。それぞれをデータベースから取得しています。メッセージを送信したときにはコメントが出るのですが、メッセージ画面遷移したときに空のコメントが出力されいます。
ご教授できたらなと思います。よろしくおねがいします。

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

php7.3.3
ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答1

0

ベストアンサー

上のほうの

PHP

1$viewData = getMsgAndBoards($m_id);

で$viewDataに値をセットしているようですが、
そのすぐ後に、

PHP

1// パラメータに不正な値が入っているかチェック 2if (empty($viewData)) { 3 error_log('エラー発生 : 指定したページに不正な値が入りました。'); 4 header('Location:mypage.php'); // マイページへ 5}

の処理がありますから、
$viewDataがemptyだった場合はmypage.phpに飛ばされ、これより下の処理に行くことはありません。
つまり、elseの「メッセージ投稿はまだありません」の出力処理に行くことはありません。

$viewData[0]['gift_id'])とか
$viewData[0]['sale_user']とか登場しますから、
$viewDataには少なくとも1個以上の要素がある前提の処理のようですが…

メッセージがないときに$viewDataにどんなデータが入るべきか整理してみてください。

投稿2019/09/24 19:56

shun-K

総合スコア508

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

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

m2B

2019/09/25 00:13

ご回答ありがとう御座います! var_dump($viewData)で、array(1) { [0]=> array(10) { ["m_id"]=> NULL ["gift_id"]=> string(2) "29" ["board_id"]=> NULL ["send_date"]=> NULL ["to_user"]=> NULL ["from_user"]=> NULL ["sale_user"]=> string(1) "5" ["buy_user"]=> string(1) "3" ["msg"]=> NULL ["create_date"]=> string(19) "2019-09-25 01:32:58" } } で取得できました。 また別ファイルでrequireで関数の処理を呼び出しているのですが、関数の処理が function getMsgAndBoards($id) { debug('msg情報を取得します。'); debug('掲示板ID :' .$id); // 例外処理 try { // DBへ接続 $dbh = dbConnect(); // SQL文作成 $sql = 'SELECT m.id AS m_id, gift_id, board_id, send_date, to_user, from_user, sale_user, buy_user, msg, b.create_date FROM message AS m RIGHT JOIN board AS b ON b.id = m.board_id WHERE b.id = :id ORDER BY send_date ASC'; $data = array(':id' => $id); // クエリ実行 $stmt = queryPost($dbh, $sql, $data); if($stmt) { // クエリ結果の全データを返却 return $stmt->fetchAll(); }else{ return false; } } catch (Exception $e) { error_log('エラー発生 :' . $e->getMessage()); } } です。 var_dumpで入っている「msg」値がNULLの場合だと、画面に出力されるのでしょうか?
shun-K

2019/09/25 15:12

var_dumpで入っている「msg」値がNULLだろうが、NULLじゃなかろうが、 var_dumpに入ってたら全部出力される仕組みになってるようです。 そもそもmessageが0件のはずなのにvar_dump($viewData)して中身があるのが 想定外なのではないですか? 原因はgetMsgAndBoardsの「SQL文作成」のとこです。 RIGHT JOINしてますので、 messageが0件でも最低でも(idが一致した)boardの件数だけのデータが抽出されてしまいます。 RIGHT JOINをINNER JOINにしたら想定どおり messageが0件のときは抽出されるデータが0件になると思います。 これで望み通りmessageが0件のときにempty判定がtrueになってくれますが、 先のコメントにも書いたとおり、次の問題が出てきますのでこれらを解決する必要があります。 (問題1) $viewDataがemptyだった場合はmypage.phpに飛ばされ、これより下の処理に行くことはありません。 (問題2) $viewData[0]['gift_id'])とか $viewData[0]['sale_user']とか 【データが1件以上あるのが前提】の処理がありますので、 その個所でエラーが出るかもしれません。(もしかしたらなんとなく上手く動くかもしれませんが)
shun-K

2019/09/25 15:26

とりあえずgetMsgAndBoardsの仕様(messageが0件でもデータ1件返ってくる)は そのままそっとしておいて… 下記で解決するかもです。 (messegeのidがnullってことはmessageが抽出されなかったということだから) <?php if (!empty($viewData)) {   ↓ <?php if (!is_null($viewData[0]['m_id'])) {
m2B

2019/09/25 16:08

!is_NULLにしたら解決できました!。 ちなみに,エラーログ吐かせたら(right joinだと) [0] => Array ( [m_id] => [gift_id] => 28 [board_id] => [send_date] => [to_user] => [from_user] => [sale_user] => 3 [buy_user] => 3 [msg] => [create_date] => 2019-09-26 00:56:15 ) ) のようになったのでSOLの書き方がよくないですね。right joinじゃなく、inner joinで条件式かいてデータ取得したほうがいいですね。 確認なんですが、right joinだとキーが取れなくても、デバッグには出力されるんですかね?([m_id] => )みたいに。 inner joinは2つテーブルのカラムが合致する場合にデータを取ってくる認識であっているのでしょうか? ちなみにコメントすると [0] => Array ( [m_id] => 19 [gift_id] => 30 [board_id] => 154 [send_date] => 2019-09-26 01:05:04 [to_user] => 5 [from_user] => 3 [sale_user] => 5 [buy_user] => 3 [msg] => 買いましたぜ! [create_date] => 2019-09-26 01:04:52 ) このように先程キーが入っていないところに値が入りますね
shun-K

2019/09/28 15:46

right joinだと2つテーブルのカラムが合致しなくても右のテーブル(つまりboardテーブル)からは データをとってきます。 その場合、m_idとかsend_dateとかmessageテーブルのカラムはnullになります。 inner joinは2つテーブルのカラムが合致する場合にデータを取ってくる認識であってます。 inner join、outer join の違いを調べるといいと思います。 right join は right outer join と同じ意味です。 left join (left outer join)はよく使いますが、right join(right outer join)は あまり使わない気がします。
m2B

2019/10/05 01:14

ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問