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

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

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

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

Q&A

解決済

1回答

1174閲覧

投稿内容がデータベースに反映されない

renren5

総合スコア12

PHP

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

0グッド

0クリップ

投稿2019/05/17 00:18

編集2019/05/19 09:09

前提・実現したいこと

PHPで掲示板サービスにてユーザー登録画面を作成中ですが、
投稿フォームからテキストの入力を行ってもデータベースに反映されない状況です。
投稿内容をテキストで入力後、投稿ボタンをクリックすると投稿内容が画面から消去
されます。この原因をご教示頂けませんでしょうか? 該当ソースコードの「index.php」に原因があるように考えています。念のため、「dbconnect.php」のファイルも添付致しました。

データベース

イメージ説明

lang

1ファイル名:index.php 2<?php 3session_start(); 4require('dbconnect.php'); 5 6if (isset($_SESSION['id']) && $_SESSION['time'] + 3600 > time()) { 7 // ログインしている 8 $_SESSION['time'] = time(); 9 10 $members = $db->prepare('SELECT * FROM members WHERE id=?'); 11 $members->execute(array($_SESSION['id'])); 12 $member = $members->fetch(); 13} else { 14 // ログインしていない 15 header('Location: login.php'); exit(); 16} 17 18// 投稿を記録する 19if (!empty($_POST)) { 20 if ($_POST['message'] != '') { 21 $message = $db->prepare('INSERT INTO posts SET member_id=?, message=?, reply_post_id=?, created=NOW()'); 22 $message->execute(array( 23 $member['id'], 24 $_POST['message'], 25 $_POST['reply_post_id'] 26 )); 27 28 header('Location: index.php'); exit(); 29 } 30} 31 32 33 34 35 36// 投稿を取得する 37$page = $_REQUEST['page']; 38if ($page == '') { 39 $page = 1; 40} 41$page = max($page, 1); 42 43// 最終ページを取得する 44$counts = $db->query('SELECT COUNT(*) AS cnt FROM posts'); 45$cnt = $counts->fetch(); 46$maxPage = ceil($cnt['cnt'] / 5); 47$page = min($page, $maxPage); 48 49$start = ($page - 1) * 5; 50$start = max(0, $start); 51 52$posts = $db->prepare('SELECT m.name, m.picture, p.* FROM members m, posts p WHERE m.id=p.member_id ORDER BY p.created DESC LIMIT ?, 5'); 53$posts->bindParam(1, $start, PDO::PARAM_INT); 54$posts->execute(); 55 56// 返信の場合 57if (isset($_REQUEST['res'])) { 58 $response = $db->prepare('SELECT m.name, m.picture, p.* FROM members m, posts p WHERE m.id=p.member_id AND p.id=? ORDER BY p.created DESC'); 59 $response->execute(array($_REQUEST['res'])); 60 61 $table = $response->fetch(); 62 $message = '@' . $table['name'] . ' ' . $table['message']; 63} 64 65// htmlspecialcharsのショートカット 66function h($value) { 67 return htmlspecialchars($value, ENT_QUOTES, 'UTF-8'); 68} 69 70// 本文内のURLにリンクを設定します 71function makeLink($value) { 72 return mb_ereg_replace("(https?)(://[[:alnum:]+$\;?.%,!#~*/:@&=_-]+)", '<a href="\1\2">\1\2</a>' , $value); 73} 74?> 75<!DOCTYPE html> 76<html lang="ja"> 77<head> 78 <meta charset="UTF-8"> 79 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 80 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 81 <title>ひとこと掲示板</title> 82 83 <link rel="stylesheet" href="../style.css" /> 84</head> 85 86<body> 87<div id="wrap"> 88 <div id="head"> 89 <h1>ひとこと掲示板</h1> 90 </div> 91 <div id="content"> 92 <div style="text-align: right"><a href="logout.php">ログアウト</a></div> 93 <form action="" method="post"> 94 <dl> 95 <dt><?php echo h($member['name']); ?>さん、メッセージをどうぞ</dt> 96 <dd> 97 <textarea name="message" cols="50" rows="5"><?php echo h($message); ?></textarea> 98 <input type="hidden" name="reply_post_id" value="<?php echo h($_REQUEST['res']); ?>" /> 99 </dd> 100 </dl> 101 <div> 102 <p> 103 <input type="submit" value="投稿する" /> 104 </p> 105 </div> 106 </form> 107 108<?php 109foreach ($posts as $post): 110?> 111 <div class="msg"> 112 <img src="member_picture/<?php echo h($post['picture']); ?>" width="48" height="48" alt="<?php echo h($post['name']); ?>" /> 113 <p><?php echo makeLink(h($post['message'])); ?><span class="name">(<?php echo h($post['name']); ?>)</span>[<a href="index.php?res=<?php echo h($post['id']); ?>">Re</a>]</p> 114 <p class="day"><a href="view.php?id=<?php echo h($post['id']); ?>"><?php echo h($post['created']); ?></a> 115 <?php 116if ($post['reply_post_id'] > 0): 117?> 118<a href="view.php?id=<?php echo 119h($post['reply_post_id']); ?>"> 120返信元のメッセージ</a> 121<?php 122endif; 123?> 124<?php 125if ($_SESSION['id'] == $post['member_id']): 126?> 127[<a href="delete.php?id=<?php echo h($post['id']); ?>" 128style="color: #F33;">削除</a>] 129<?php 130endif; 131?> 132 </p> 133 </div> 134<?php 135endforeach; 136?> 137 138<ul class="paging"> 139<?php 140if ($page > 1) { 141?> 142<li><a href="index.php?page=<?php print($page - 1); ?>">前のページへ</a></li> 143<?php 144} else { 145?> 146<li>前のページへ</li> 147<?php 148} 149?> 150<?php 151if ($page < $maxPage) { 152?> 153<li><a href="index.php?page=<?php print($page + 1); ?>">次のページへ</a></li> 154<?php 155} else { 156?> 157<li>次のページへ</li> 158<?php 159} 160?> 161</ul> 162 </div> 163</div> 164</body> 165</html> 166

PHP

1<?php 2try { 3 $db = new PDO('mysql:dbname=mini_bbs;host=localhost;charset=utf8', 'root', 'root'); 4} catch (PDOException $e) { 5 echo 'DB接続エラー: ' . $e->getMessage(); 6} 7?>

試したこと

echo LINE . PHP_EOL;をif文の内と外に配置したところ、以下の工程のデータ挿入の前の処理で止まってることがわかりました。

PHP

1// 投稿を記録する 2 3 echo __LINE__ . PHP_EOL; 4if (isset($_POST)) { 5 if (isset($_POST['message']) && isset($_POST['reply_post_id'])) { 6 echo __LINE__ . PHP_EOL; 7 $message = $db->prepare('INSERT INTO posts SET member_id=?, message=?, reply_post_id=?, created=NOW()'); 8 $message->execute(array( 9 $member['id'], 10 $_POST['message'], 11 $_POST['reply_post_id'] 12 )); 13header('Location: index.php'); exit(); 14} 15echo __LINE__ . PHP_EOL; 16} 17echo __LINE__ . PHP_EOL;

投稿画面イメージ

イメージ説明
画像の右上の番号、24(INSERT文の前の行の行番号)のみ表示されていないです。

動作環境

PHP :7.3.1
DB :MySQL
動作環境:Mac(MAMP)

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

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

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

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

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

m.ts10806

2019/05/17 00:29

> 登録フォームから各項目の入力を行ってもデータベースに反映されない状況です。 入力を行ったうえできちんと送信ボタン押されてますか? また起きた現象をもう少し具体的に記載してください。 あと、処理はどこまで正常に通ってるかデバッグ確認して結果を質問本文に追記してください。
m.ts10806

2019/05/17 00:32

PHPのバージョン、DBの種類・バージョン あとPHPが動作している環境(Windows,CentOSなど)追記してください。 PHPをどうやって入れたか(WindowsであればXAMPPとか、全て個別でインストールしたとか)も追記願います。
m.ts10806

2019/05/17 00:34 編集

念のため、dbconnect.phpの内容、$_SESSIONがどこで設定されるかもご提示願います。 HOST,ID,PASSなどは適当にマスクかけてもらって構いません。
renren5

2019/05/19 08:46

mts10806さん いろいろ不備があり、申し訳ございません。 ご指摘いただいた箇所について、以下にお答えさせて いただきます。 >入力を行ったうえできちんと送信ボタン押されてますか? テキストを入力し、投稿ボタンを押すと画面から入力した テキストが消去されます。通常であれば、この段階でDBに反映されると 思います。 >処理はどこまで正常に通ってるかデバッグ確認して結果を質問本文に追記してください。 >PHPのバージョン、DBの種類・バージョン >あとPHPが動作している環境(Windows,CentOSなど)追記してください。 >PHPをどうやって入れたか(WindowsであればXAMPPとか、全て個別でインストールしたとか)も追記願います。 追記致しました。ご確認お願いします。 >念のため、dbconnect.phpの内容、$_SESSIONがどこで設定されるかもご提示願います。 HOST,ID,PASSなどは適当にマスクかけてもらって構いません。 承知致しました。 追記しておきます。
guest

回答1

0

ベストアンサー

php

1if (!empty($_POST)) {

これ、何を参考にしました? どこかにこう書きましょうってありましたか? (まさかprogate?)
ここが成立しないと、このifブロックの内側に入ってこない→INSERT INTO文が実行されないです。
それを検証するのに、ifブロックの内と外にデバッグ出力を仕込んだらいいです。
ここを通ったというのがわかるように、例えば
PHP: 自動的に定義される定数 - Manual
にある _ _ LINE _ _ を使ってecho __LINE__ . PHP_EOL;とかをあちこちに仕込めば、
そこを処理が通過したら行番号が出力されたりします。

下記、老婆心ながら。

POST受信しているかどうかの判定にempty()を使うべきではないです。
PHP isset, empty, is_null の違い早見表 - Qiita
文字列長ゼロの文字列や数値ゼロを、empty()はTRUE判定してしまいます。
今回のempty($_POST)に関しては、一つでも値を格納していればTRUEになるかもしれませんが、
その延長でもしもempty($_POST['message'])などと使い出すと(今回は良くても)いずれどこかで間違うかもしれません。
if (isset($_POST['message']))みたいな書き方のほうが良いかと。

テーブルpostsの構造を見ると、
Nullが許されない、かつ自動で値が詰められないカラムが
message
member_id
reply_post_id
の3つです。
これらを引き渡すために
$member['id'],
$_POST['message'],
$_POST['reply_post_id']
を渡していますが、ちゃんとこれらのパラメータを受信できているか検証しないと
クエリー実行時エラーになります。

php

1if (isset($_POST['message']) && isset($_POST['reply_post_id'])) { 2}

くらいは最低限やらないといけません。
POST送信するフォーム上で、

<input type="hidden" name="reply_post_id" value="<?php echo h($_REQUEST['res']); ?>" />

としていますが、そもそも$_REQUEST['res']に値が入っているのかどうか、
入っていないときにここが空欄になりますが、
そのときの挙動として今回の問題が起きているような気がします。
テーブルposts上でカラムreply_post_idはint型なので、
空欄は許されません
ので。
せめてゼロを詰めるとか、NULLを許可するなどしないといけないのではないかと。

もしもApache上でphpを実行しているなら、
PHPのエラー表示設定について - Qiita
を参考に、php.iniや.htaccessに記述する方法で
エラー出力をwebブラウザに出せるようにしといた方がデバッグしやすいです。
また、apacheのerror_logにも手がかりが残るので、
そちらもチェックしましょう。

投稿2019/05/17 01:09

編集2019/05/17 01:18
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

m.ts10806

2019/05/17 01:33

Udemyの可能性がないとも言えませんね 受けたことないですけどオンライン学習系は結構雑なイメージがあります。
退会済みユーザー

退会済みユーザー

2019/05/17 01:37

この質問に限らず、なぜか決まって、 エラー情報をwebブラウザに出力する方法と、 empty()じゃなくisset()使おうよってのを伝えるところから回答が始まるので、 どっかのオンライン学習サービスが良からぬやり方を教えているような気がして いやな時代だなぁと。
m.ts10806

2019/05/17 01:43

学習要綱のもととなる教材とか書籍が古いものなのかもしれませんね。 書籍でも「PHP7対応」と書いていてもPHP5時代(それも5.3とか)のものとちょっと焼き直して「PHP7でも動くよ」くらいの書き方しかしてないのもありますし、セキュリティ考慮してなかったりとか。 Qiitaの評価数高い記事読んだほうがよっぽど有用だと思います。 それでも学ぶ人がいるのでいい商売だなぁと思いますけど、この手のオンライン講座の受講者ってたぶん現場でほとんど使い物にならないんじゃなかなと懸念してます。商売の邪魔するわけじゃないですけど、実際に上がってくる質問見たら質問でやりたいこと以前に突っ込むことが多すぎて。
退会済みユーザー

退会済みユーザー

2019/05/20 12:58

BAついたけど、どうやって解決に至ったか、自分でまとめて回答として投稿してもらいたいです。今後の参考までに。
renren5

2019/05/20 12:59

SQLのデータ(reply_post_id)でNullを許可したら、バグが改善されました。 emptyとissetの違いなど、周辺知識についても、ご教授して頂きありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問