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

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

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

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

PHP

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

Q&A

解決済

3回答

8046閲覧

formでPOST送信しても$_POSTが空になってしまう

xsU4SiGdN

総合スコア4

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

PHP

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

0グッド

0クリップ

投稿2020/03/01 17:32

前提・実現したいこと

PHPでTwitterクローンを作成しています。
テキストメッセージをHTMLのform要素からPOST送信し、PHPでそれを$_POSTから取り出してデータベースに登録しようとしています。

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

投稿メッセージをデータベースに挿入する処理を行う際、47-57行目のHTMLのform要素でaction属性に""を指定し、method属性にPOSTを指定して、投稿内容を$_POSTから取得しようとしたのですが、19行目でempty($_POST)がtrueを返してしまい、投稿内容を取得できません。

該当のソースコード

PHP

1<?php 2session_start(); 3require('dbconnect.php'); 4 5if (isset($_SESSION['id']) && $_SESSION['time'] + 3600 > time()) { 6 // logged in 7 $_SESSION['time'] = time(); 8 9 $members = $db->prepare('SELECT * FROM members WHERE id=?'); 10 $members->execute(array($_SESSION['id'])); 11 $member = $members->fetch(); 12} else { 13 // not logged in 14 header('Location: login.php'); 15 exit(); 16} 17 18// record a post 19if (!empty($_POST)) { 20 if ($_POST['message'] != '') { 21 $message = $db->prepare('INSERT INTO posts SET member_id=?, message=?, created=NOW()'); 22 $message->execute(array($member['id'], $_POST['message'])); 23 24 header('Location: index.php'); 25 exit(); 26 } 27} 28?> 29 30<!DOCTYPE html> 31<html lang="ja"> 32<head> 33 <meta charset="UTF-8"> 34 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 35 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 36 <title>ひとこと掲示板</title> 37 38 <link rel="stylesheet" href="style.css" /> 39</head> 40 41<body> 42<div id="wrap"> 43 <div id="head"> 44 <h1>ひとこと掲示板</h1> 45 </div> 46 <div id="content"> 47 <form action="" method="POST"> 48 <dl> 49 <dt><?php echo htmlspecialchars($member['name'], ENT_QUOTES); ?>さん、メッセージをどうぞ</dt> 50 <dd> 51 <textarea name="message" cols="50" rows="5"></textarea> 52 </dd> 53 </dl> 54 <div> 55 <input type="submit" value="投稿する" /> 56 </div> 57 </form> 58 </div> 59</div> 60</body> 61</html>

試したこと

ログインはできているはずです。
19行目からはじまるブロックの後にelse節を作って挙動を確認しました。
フォームに何かメッセージ入力してを投稿するとempty($_POST)がtrueを返しますが、フォームを空にして投稿すると、なぜかempty($_POST)がfalseを返します。

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

OS: Ubuntu 18.04
サーバー環境など: XAMPP 7.4.2

『よくわかるPHPの教科書』 https://book.mynavi.jp/ec/products/detail/id=89743 を踏襲して作成しているのですが、同書のサンプルファイル https://book.mynavi.jp/files/user/support/9784839964689/PHP_samplefile.zip のコードで試しても同じ状況が起きてしまいます。

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

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

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

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

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

guest

回答3

0

フォームに何かメッセージ入力してを投稿するとempty($_POST)がtrueを返しますが、フォームを空にして投稿すると、なぜかempty($_POST)がfalseを返します。

これが確かなら、ブラウザで POST 内容を確認してください。開発ツールを使うことで切り分けできます。

19行目からはじまるブロックの後にelse節を作って挙動を確認しました。

こちらの手法に問題があるのでは?
if の条件は!empty($_POST)ですが、読み間違えていませんか?

else ではなく、if の直前で、var_export((bool)!empty($_POST)) とすると分岐条件時の値を確認できます。

追記
$_POST のような、書き換え可能なグローバル変数を使用することは、デバッグを複雑にします。
参考:スーパーグローバル変数に直接アクセスしない方がいい理由

filter_input()で代替することで、見通しを良くすることが可能なので、本件でも試してみると良いです。

投稿2020/03/01 20:07

編集2020/03/01 20:34
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

xsU4SiGdN

2020/03/02 03:43

回答をありがとうございます。 まず、Chromeの開発者ツールでヘッダを調べたところ、Form Dataにメッセージの内容が表示されていたので、POST送信はできており、再度index.phpにGETリクエストしています。しかし、フォームを空にして送信すると、やはり送信はできているようですが、その後GETリクエストを送っていないことがわかりました。 「19行目からはじまるブロックの後にelse節を...」については誤解を招く書き方をしてしまい申し訳ありませんでした。 フォームに内容を入れて送信するとelse節のブロックに入り、内容を入力して送信すると19行目の if (!empty($_POST)) { のブロックに入るので「フォームを空にして投稿すると...empty($_POST)がfalseを返」すと推測したのでした。 19行目の直前に print(var_export((bool)!empty($_POST))); とすると、falseを表示するので、やはり$_POSTは空のようです。 また、19行目の直前に $message = filter_input(INPUT_POST, 'message'); printf('messageは%sです。', $message); とすると、「messageはです。」と出力されます。 まとめると、POST送信はできているが、再度index.phpを呼び出すと$_POSTが空になってしまうようです。 この前段階でログインページを作成した際はこのようなことはなかったのですが……。 まったく別の点に問題があるのでしょうか?
退会済みユーザー

退会済みユーザー

2020/03/02 04:32

> フォームに内容を入れて送信するとelse節のブロックに入り、内容を入力して送信すると19行目の if (!empty($_POST)) { のブロックに入る 「内容を入れて」と「内容を入力して」の違いがわかりません。 同じ動作で違う判定がされるということでしょうか? > POST送信はできているが、再度index.phpを呼び出すと$_POSTが空になってしまうようです。 こちらは、index.php への遷移が GET であることを確認したのでは? indx.php に POST はされていないので、当然、$_POST は空になります。 ちなみに、提示されているファイルが index.php なのでしょうか?
xsU4SiGdN

2020/03/02 08:28

> 「内容を入れて」と「内容を入力して」の違いがわかりません。 > 同じ動作で違う判定がされるということでしょうか? 「フォームに内容を入れて送信するとelse節のブロックに入り、内容を入力して送信する」は 「フォームに内容を入れて送信するとelse節のブロックに入り、内容を『空に』して送信する」の間違いでした。混乱を招いてしまい申し訳ありませんでした。 > こちらは、index.php への遷移が GET であることを確認したのでは? > indx.php に POST はされていないので、当然、$_POST は空になります。 > ちなみに、提示されているファイルが index.php なのでしょうか? はい。提示しているファイルがindex.phpです。 index.php内のformでPOST送信して、その内容をindex.phpの冒頭で$_POSTから取り出そうとしていました。 下記の自己解決の通り、$_POSTが空であるというのは私の誤解で、24行目のリダイレクト後の$_POSTの内容を調べていたので、空なのも当然なのでした。 見当違いの問題設定で申し訳ありませんでしたが、おかげで「$_POSTに直接アクセスせずにfilter_input()を用いてコードを疎結合にすべき」などの点が参考になりました。ありがとうございます。
guest

0

!empty($_POST)

しているなら

if ($_POST['message'] != '') {

は無効ですね
filter_inputつかってみてください

投稿2020/03/02 00:32

yambejp

総合スコア115010

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

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

0

自己解決

解決方法

21, 22行目を

PHP

1$message = $db->prepare('INSERT INTO posts SET message=?, member_id=?, reply_post_id=?, created=NOW()'); 2$message->execute(array($_POST['message'], $member['id'], $member['id']));

とすることで解決しました。

原因

データベーステーブルにreply_post_idというカラムを設定していたのですが、デフォルト値を決めていなかったため、データの挿入に失敗していたようです。

誤解

24行目で、データベースへの挿入の正否に関わらず

PHP

1header('Location: index.php');

として最初に提示したものと同じファイルであるindex.phpにリダイレクトしていたため、$_POSTが空だと勘違いしていたのでした。

投稿2020/03/02 08:29

xsU4SiGdN

総合スコア4

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問