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

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

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

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

PHP

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

Q&A

解決済

2回答

1063閲覧

formの入力値がDBに保存されない

tunnel

総合スコア30

MySQL

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

PHP

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

0グッド

0クリップ

投稿2019/05/25 04:52

入力した値が$_POSTに入ってそれを取得してmysql文でインサートするという流れはできているはずなのですがDBを見てみると値がありません。

reply_post_idがあるせいなのかとも思い一度消して見ましたが関係ありませんでした。

php

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

php

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

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2019/05/25 05:03 編集

このコードを実行している環境の情報、レンタルサーバー上なのかパソコンなのか、パソコンならXAMPPやMAMPなどなのか、それとも別の実行環境か、例えばXAMPPのapacheで動かしているならapacheが出力するaccess_logやerror_logを点検してエラーメッセージが記録されていないか、など確認の上、質問文中に補足お願いします。
guest

回答2

0

//投稿を記録する if (!empty($_POST)) { if ($_POST['message'] != '') { $message = $db->prepare('INSERT INTO posts set member_id=?, message=?, reply_post_id=?, created=NOW()'); $message->execute(array( $member['id'], $_POST['message'], $_POST['reply_post_id'] )); header('Location: index.php'); exit(); } }

この箇所、ふつうはこうならないかなぁ。

//投稿を記録する if (isset($_POST['message']) && isset($_POST['reply_post_id'])) { if (($_POST['message'] != '') && (is_numeric($_POST['reply_post_id']))) { try { $db->beginTransaction(); $message = $db->prepare('INSERT INTO posts(member_id, message, reply_post_id, created) set member_id=?, message=?, reply_post_id=?, created=NOW()'); $message->execute(array( $member['id'], $_POST['message'], $_POST['reply_post_id'] )); $db->commit(); header('Location: index.php'); exit(); // ←これがこれでいいかどうかは保留。 } catch (PDOException e) { echo e->getMessage(); // ←あくまで仮。 } } }

!empty($_POST)は横着がすぎるので、
本当にほしいPOST受信パラメータを使ってisset()で判定するべきかと。
PHP isset, empty, is_null の違い早見表 - Qiita

それと、この場面に至るまでに、ちゃんと$memberや$member['id']に値が入ってきているかも確認しないと。
$memberを抽出するのに使っている$_SESSION['id']に値を設定している箇所がないので、
デバッグ中の何かの拍子に値が飛んじゃっていたりしないかとか。
なので、$_SESSION['id']をisset()で判定するだけじゃなくて、
意図した値が入っているか念入りにバリデーション加えてもいいんじゃないかと思ったり。
空文字列でも値は値なので$_SESSION['id']が存在することになったりもしますし。

さらに、INSERET INTO文でテーブル名のすぐあとにカラム名を列挙してみました。
のちにテーブルが拡張されてカラムが追加されたりしたとき、エラーになるのを防ぐために。
同じような理由で、SELECT文においても「*」で省略せずカラム名は抽出したいものすべて記述します。

念のため、beginTransaction()とcommit()も設けてデータベースへの反映を意図してみたり。
さらに念のために、try~catchで囲ってみたり。

また、dbconnect.phpの末尾で

?>

で閉じていますが、もしもその記号のあとに改行コードとかあると、
不要な文字出力が生じて header() によるリダイレクトが利かなかったりするかもしれません。

//dbconnect.php <?php try { $db = new PDO('mysql:dbname=mini_bbs;host=localhost;charset=utf8', 'root', 'root', [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false, ]); } catch (PDOException $e) { echo 'DB接続エラー:' . $e->getMessage(); }

とかやってデータベース操作時のエラーを例外としてキャッチできるようにするのも忘れずに。

投稿2019/05/25 05:22

編集2019/05/25 05:38
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

ベストアンサー

実行されているはずのSQLを直にDBに対して実行してみた場合はどうでしょうか?
基本的な流れとしては、プログラムから実行する前にDBに対して実行します。
DBもPHPからすると外部サービスなので、直に実行して実行できないものはプログラムから実行しても当然できません。
PHPから実行するときもがっつりコードを組んでから実行するのではなく「こういう値が来るはず」というのを固定値で埋め込んで実行してそれが想定通り動いてからがっつり組みます。
必要最小限の処理だけを入れたミニマムコードですね。ミニマムコードで動かないものはそれも当然全体ロジックを組んでも動きません。

あとは、DB接続時だけではなく実行時にもきちんとExceptionを拾うようにしてください。
特にINSERT,UPDATE,DELETEのようにDBに影響がある処理を行うときは、トランザクション開始~SQL実行~コミット/ロールバックする流れを作るよう強くススメます。

php

1try { 2 $db->beginTransaction(); 3 $message = $db->prepare('INSERT INTO posts set member_id=?, message=?, reply_post_id=?, created=NOW()'); 4 $message->execute(array( 5 $member['id'], 6 $_POST['message'], 7 $_POST['reply_post_id'] 8 ));'root'); 9 $db->commit(); 10} catch (PDOException $e) { 11 $db->rollBack(); 12 die('DB接続エラー:' . $e->getMessage()); 13} 14

できれば何もせずheader()でリダイレクトさせるのではなく、
「完了しました」などメッセージを画面に出したほうが安全とは思います。

あと細かいのですが・・・・
「PHPコードだけどそれ以降何もない」のであれば?>はないほうがいいです。
改行とかスペースとか何かで入ってしまえば画面に出力されてしまってそれが思わぬ問題を引き起こすこともあるので。

追記:
m6uさんがdbconnect.phpの改修内容記載してくれていますが、
DB接続時にエラーオプションは必ず設定しておいてください。

投稿2019/05/25 05:03

編集2019/05/25 05:44
m.ts10806

総合スコア80850

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

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

退会済みユーザー

退会済みユーザー

2019/05/25 05:33

DB接続時に例外スローするよう設定しないと、せっかくtry~catchしても・・・。
m.ts10806

2019/05/25 05:41

あ、本当ですね。 m6uさんのdbconnect.phpの改修内容は必須ですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問