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

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

詳細はこちら
PHP

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

Q&A

解決済

2回答

1137閲覧

掲示板の投稿を表示させたい。

MakotoIshizawa

総合スコア32

PHP

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

0グッド

1クリップ

投稿2019/09/18 06:27

編集2019/09/18 07:52

以前、質問した掲示板の続きです。
PHPのバージョンは5.2.4です。
https://teratail.com/questions/212172
新たに問題が出てきて、苦戦しています。
(ここで指摘していただいた変換文字の表示部分の工夫はまだしていません)

HTML部分のコメント欄のrequiredが効きません。
phpでissetで名前とコメントをが入力された場合のif文も書いてるのに、コメントが空でも書き込まれてしまいます。
issetとemptyの違いも一応調べてissetに変えてみましたが、理解がおかしいのでしょうか?
https://qiita.com/shinichi-takii/items/00aed26f96cf6bb3fe62

そして表示部分、file_existsで存在確認しifで分岐しています。
書き込まれた内容があるのに(ファイルが存在するのに)、投稿はまだありませんと表示されてしまいます。

if文の直前にvar_dumpで中身を表示するとNULLを返されました。

何がいけないのでしょうか。
そして原因に辿り着くためには何をすればよいのでしょうか。
(前の質問とは別のファイルで続きをしています)

php

1<?php 2/*もしポストで送信されたら以下の処理を行いGET送信でリダイレクトする(更新時の二重書き込み防止)*/ 3if ( $_SERVER[ 'REQUEST_METHOD' ] === 'POST' ) { /*もしPOSTで送信されたら*/ 4 5 /*フォームで送信された値を受け取り、テキストファイルに保存する。 6 その際1行ごとに「{番号}<>{名前}<>{コメント}<>{投稿された時間}」と言う形で保存する*/ 7 /*変数の定義*/ 8 $filename = "keijiban.txt"; /*保存するファイル*/ 9 $name = $_POST[ "name" ]; /*投稿者の名前*/ 10 $comment = $_POST[ "comment" ]; //投稿コメント 11 $date = date( "Y-m-d H:i" ); /*投稿日時*/ 12 13 $search = array("\r\n", "\r", "\n","<>"); //置き換え時の検索文字 14 $replace = array("<<改行>>","<<改行>>","<<改行>>","&lt;&gt;"); //置き換える文字 15 16 /*投稿番号の定義*/ 17 if ( file_exists( $filename ) ) { /*ファイルの存在確認。*/ 18 //最後の行にプラス1 19 $ret_array = file( $filename ); 20 $lastline = $ret_array[ count( $ret_array ) - 1 ]; 21 $num = explode( '<>', $lastline ); 22 $lastnum = $num[ 0 ] + 1; 23 } else { /*ファイルが無かった場合変数の定義を1とする*/ 24 $lastnum = 1; 25 } 26 //書き込み内容 27 $hozon = $lastnum . "<>" . str_replace( $search, $replace, $name ) . "<>" . str_replace( $search, $replace, $comment ) . "<>" . $date . "\n"; 28 //投稿部分 29 if ( isset( $name ) && isset( $comment ) ) { /*もし名前とコメントが送信されたら*/ 30 file_put_contents( $filename, $hozon , FILE_APPEND | LOCK_EX);//排他ロックをかけ追記モードで書き込み 31 } 32 //削除部分 33 /*if ( !empty( $_POST[ 'deleteNO' ] ) ) {//もし、削除番号がポスト送信されたら 34 $deleteNO = $_POST[ 'deleteNO' ]; //削除番号の変数定義 35 $ret_array = file( $filename ); //ファイルを配列として読み込む 36 unlink($filename); 37 foreach ( $ret_array as $value ) { //ループ 38 $bangou = explode( "<>", $value ); //<>で分割し投稿番号取り出す 39 if ( $deleteNO != $bangou[ 0 ] ) { //もし読み込んだ番号と送信した番号が違ったら 40 file_put_contents( $filename, $hozon , LOCK_EX);//排他ロックをかけ上書き 41 } 42 } 43 }*/ 44 header( 'Location: keijiban.php' ); 45 exit; 46} 47?> 48<!doctype html> 49<html lang="ja"> 50<head> 51<meta charset="utf-8"> 52<title>簡易掲示板</title> 53</head> 54 55<body> 56<p> 57<form action="keijiban.php" method="post" > 58 <label for="name-field">お名前<span style="color: red;">【必須】</span><br> 59 </label> 60 <input type="text" name="name" id="name-field" required="required"> 61 <label for="comment">コメント<span style="color: red;">【必須】</span></label> 62 <br> 63 <textarea name="comment" cols="30" rows="3" id="comment" required="required">  64</textarea> 65 <input type="submit" value="投稿"> 66</form> 67<?php 68 var_dump($filename); 69if ( file_exists( $filename ) ) { 70foreach ( $ret_array as $value ) { 71 $bunkatu = explode( "<>", $value ); 72 foreach ( $bunkatu as $value2 ) { 73 echo $value2 . "<br>\n"; 74 } 75} 76} else { 77 echo "まだ投稿はありません"; 78} 79?> 80<!--<form action="keijiban.php" method="post"> 81 <P> 82 <label for="deleteNO" >削除対象番号</label> 83 <input type="text" name="deleteNO" id="deleteNO" > 84 </p> 85 <input type="submit" value="削除"> 86</form>--> 87</body> 88</html>

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

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

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

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

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

guest

回答2

0

ベストアンサー

コメント欄のrequiredが効きません。

それはそうでしょう。textareaの中身が空になっていませんから。

HTML

1<textarea name="comment" cols="30" rows="3" id="comment" required="required"></textarea>

textareaはすぐ閉じてください
1回の改行マークまでは許されますがrequiredを前提にするならすぐ閉じた方がより直感的

postデータの取扱

検証のため一度requiredは外して以下確認ください

php

1<?PHP 2$name = filter_input(INPUT_POST, "name",FILTER_VALIDATE_REGEXP,["options"=>["regexp"=>"/./"]]); 3$comment = filter_input(INPUT_POST, "comment",FILTER_VALIDATE_REGEXP,["options"=>["regexp"=>"/./"]]); 4var_dump([$name,$comment]); 5?> 6 7<form method="post" > 8 <label for="name-field">お名前<span style="color: red;">【必須】</span><br> 9 </label> 10 <input type="text" name="name" id="name-field"> 11 <label for="comment">コメント<span style="color: red;">【必須】</span></label> 12 <br> 13 <textarea name="comment" cols="30" rows="3" id="comment"> 14</textarea> 15 <input type="submit" value="投稿"> 16</form>
  • postデータが送られてこない場合はnullになります
  • 空の文字が送られてきた場合はfalseになります

仮に空の文字が送られてきても、「空で送られてきた」という情報が渡るので
issetでやる場合は

PHP

1if(isset($_POST["name"]) and $_POST["name"]!==""){ ・・・

みたいな処理になります

古い書き方

PHP

1<?PHP 2$options=array("options"=>array("regexp"=>"/./")); 3$name = filter_input(INPUT_POST, "name",FILTER_VALIDATE_REGEXP,$options); 4$comment = filter_input(INPUT_POST, "comment",FILTER_VALIDATE_REGEXP,$options); 5var_dump(array($name,$comment)); 6?> 7 8<form method="post" > 9 <label for="name-field">お名前<span style="color: red;">【必須】</span><br> 10 </label> 11 <input type="text" name="name" id="name-field"> 12 <label for="comment">コメント<span style="color: red;">【必須】</span></label> 13 <br> 14 <textarea name="comment" cols="30" rows="3" id="comment"> 15</textarea> 16 <input type="submit" value="投稿"> 17</form>

投稿2019/09/18 06:41

編集2019/09/18 08:25
yambejp

総合スコア116690

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

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

MakotoIshizawa

2019/09/18 06:47

ありがとうございます。requiredは解決しました。 知らなかったです、勉強になりました。
MakotoIshizawa

2019/09/18 06:48

そうですよね、中身が入ってるからですよね。 うかつでした。
MakotoIshizawa

2019/09/18 06:52

issetに関しても同じ理由ですよね
MakotoIshizawa

2019/09/18 06:54

ファイルも内容もあるのにNULLで返される謎がわかりません
yambejp

2019/09/18 07:01

issetの注意事項を追記しました
MakotoIshizawa

2019/09/18 07:18

syntax error,が出てしまいました。 $name = filter_input(INPUT_POST, "name",FILTER_VALIDATE_REGEXP,["options"=>["regexp"=>"/./"]]);の行です
MakotoIshizawa

2019/09/18 07:22

issetの部分、isset以外だともっとすっきりしたコードになったりしますか?
yambejp

2019/09/18 07:30

> syntax error, コピペで動くように書いてあるのでそれはありえません。 ご利用のPHPのバージョンが相当古かったりします?
MakotoIshizawa

2019/09/18 07:42

調べてみたらバージョン5.2.4でした
退会済みユーザー

退会済みユーザー

2019/09/18 07:45

5.2.4 はEOL。。 今後は利用してるPHPのバージョンを質問に記載しましょう。今回は追記しましょう
MakotoIshizawa

2019/09/18 07:50

ありがとうございます。 そのようにします。 今までバージョンも知らずに書いていました。 以前もバージョンが原因かもしれない不具合がありましたが、バージョンを調べる方法まで調べていませんでした。
退会済みユーザー

退会済みユーザー

2019/09/18 08:17

array の省略記法は 5.4 以降
MakotoIshizawa

2019/09/18 08:18

因みにfilter_inputについて調べていたら https://teratail.com/questions/63786 のような記事がたくさん出てきましたが、今回の様な場合もfilter_inputを使って書いたほうが良いということでしょうか?
MakotoIshizawa

2019/09/18 08:20

array の省略記法とはどの部分ですか?
退会済みユーザー

退会済みユーザー

2019/09/18 08:21

省略記法 : [ key => value ] 通常記法 : array ( key => value );
yambejp

2019/09/18 08:23

> array の省略記法は 5.4 おっと、調整します
MakotoIshizawa

2019/09/18 08:24

ありがとうございます。 その様に書き直してみます。
yambejp

2019/09/18 08:38

> array(2) { [0]=> NULL [1]=> NULL } まずはpostしないとnameやcommentを受け取っていないというnullが返ります 何も入れずに「投稿」するとfalseに変わると思います これはデータは送られてきたけど、想定外のデータだという意味です。 nameやcomentになにか入力して投稿すると送った値が表示されます
MakotoIshizawa

2019/09/18 08:44

それが送ってもなにも表示されないんです
MakotoIshizawa

2019/09/18 08:46

しかも、さっきまでは書き込めていた名前とコメントまで書き込まれなくなりました。 投稿番号もなく時間だけ。 1<>jbと<>てすと <<改行>><>2019-09-18 14:26 2<>まこと<> <<改行>><>2019-09-18 14:29 3<>まこと<> <<改行>><>2019-09-18 14:30 4<>まこと<> <<改行>><>2019-09-18 14:30 5<>まこと<> <<改行>>テスト<>2019-09-18 14:32 6<>マコト<>テスト <<改行>><>2019-09-18 14:45 7<>まこと<>テスト <<改行>><>2019-09-18 14:57 8<>まこと<> <<改行>><>2019-09-18 14:57 9<>まこと<> <<改行>><>2019-09-18 15:45 10<>まこと<> <<改行>><>2019-09-18 15:45 11<>まこと<>テスト<>2019-09-18 17:30 12<>まこと<>テスト<>2019-09-18 17:34 17:39 2019/09/1817:39 2019/09/1817:42 2019/09/1817:45 2019/09/18
yambejp

2019/09/18 08:50

> さっきまでは書き込めていた名前とコメント 書き込む処理は一切書いてないですよ まずはpostしたデータがきちんと受け取れるところをクリアしてから 次のステップにすすんでください
MakotoIshizawa

2019/09/18 08:58

別のファイルに上記のコードだけを書いて試すていうことでしょうか
yambejp

2019/09/18 09:04

なんでもいいのでコピペして実験してください
MakotoIshizawa

2019/09/18 09:09

別のファイルではarray(2) { [0]=> string(9) "まこと" [1]=> string(9) "テスト" } と表示されました。 もとのファイルに入れるとだめです
MakotoIshizawa

2019/09/18 09:11

もとのファイルでは array(2) { [0]=> NULL [1]=> NULL } です
yambejp

2019/09/18 09:48

送り元のファイルにformを書いて、actionに受け側のファイルを指定 受け側のファイルにphpのソースを転記
退会済みユーザー

退会済みユーザー

2019/09/18 09:51

中身はどーでも良いけど、5.2 捨てるとこから始めるべきでは?
MakotoIshizawa

2019/09/18 09:54

訳あって今はこの環境でやらないといけませんので
yambejp

2019/09/18 10:01

ちなみにファイルI/Oでうまくいかないならfopen/flock/fwrite/fcloseで処理してください
MakotoIshizawa

2019/09/18 10:06

はい 今日はもう時間が無いのでここまでにします。 みなさまありがとうございました。 また後日順を追って検証していきたいと思います。
退会済みユーザー

退会済みユーザー

2019/09/18 10:15

> 訳あって今はこの環境でやらないといけませんので 訳とかどーでもいいです。中身を考えるより先に、捨てることを考えてください。 掲示板機能であれば、「htmlspecialchars」と「暗号学的に安全な乱数の発生」で詰みます。 https://blog.tokumaru.org/2014/12/phpphp.html
MakotoIshizawa

2019/09/20 06:23

そうなんですね。 ありがとうございます。 新しくなるには色々と経緯がありますよね。
退会済みユーザー

退会済みユーザー

2019/09/20 06:41 編集

ほんと(あなたのいい)訳なんてどうでもいい 特定のドメイン(ディレクトリ)以下は php7.x だが他は php5.x も設定でできるし OSレベルでインストール可能なものが限られてるならそれはいうべき
guest

0

うまく表示できていたときのコードを以前の質問からコピペして、色々試してみました。
結論を言うと、うまくいっていたコードの表示部分の頭に$filname="keijiban";がありました。
冒頭でも同じ定義をしていたために、余計なものと思い削除しました。
恐らくそれがいけなかったようです。
header( 'Location: keijiban.php' );
exit;
が邪魔したのでしょうか?
(その後 header( 'Location: keijiban.php' );
exit;を削除し、該当箇所の$filename = "keijiban.txt";を削除してみたところうまくいきました。
同時に、更新で空投稿されるようにもなりましたが)
よくわかりませんが結果的には、$filname="keijiban";を再定義することでうまくいきました。
未定義の$filenameをforeachしたためにNULLだったのかもしれません。
うまくいったコード

php

1$filename = "keijiban.txt"; 2if ( is_file( $filename ) ) { 3 $ret_array = file( $filename ); 4 foreach ( $ret_array as $value ) { 5 $bunkatu = explode( "<>", $value ); 6 foreach ( $bunkatu as $value2 ) { 7 echo str_replace($search , $replace, $value2 )."<br>\n"; 8 } 9 } 10}else{ 11 echo "まだ投稿はありません"; 12}

質問文の中の該当箇所

php

1<?php 2 var_dump($filename); 3if ( file_exists( $filename ) ) { 4foreach ( $ret_array as $value ) { 5 $bunkatu = explode( "<>", $value ); 6 foreach ( $bunkatu as $value2 ) { 7 echo $value2 . "<br>\n"; 8 } 9} 10} else { 11 echo "まだ投稿はありません"; 12} 13?>

投稿2019/09/20 09:56

編集2019/09/24 03:34
MakotoIshizawa

総合スコア32

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問