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

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

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

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

Q&A

解決済

1回答

1020閲覧

掲示板で、編集や削除のために番号を指定する時、その番号がない場合「該当する投稿はありません」と表示したい

MakotoIshizawa

総合スコア32

PHP

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

0グッド

0クリップ

投稿2019/10/11 09:38

編集2019/10/11 10:22

PHP5.2.4(バージョンは指定による)
掲示板を作る課題に取り組んでいます。
in_arrayで分岐して実現しようとしました。
編集番号指定のところで試していますが、
現在は、送信した番号があっても表示されてしまいます。
昨日はうまくいっていたはずなのですが、コードを直した時にどこか変えてしまったせいかうまくいかなくなってしまいました。
具体的には、投稿内に送信した番号があるときにも「該当する投稿がありません」と表示されてしまいます。
コードで言うと、
$exの中に$H_noがあるのに$hMesaageがechoされます。
何が悪いのでしょうか。

var_dumpして気づいたのですが、なぜか送信した番号の投稿が$exの中からなくなっています。

php

1 if ( !in_array( $H_no, $ex, true )|| empty( $ex ) ) { //投稿番号の中に送信された番号がないか、ファイルの中身が無い時 2 $hMessage = "該当する投稿がありません"; 3} 4```のように書きました。 5表示させるフォームは以下。 6```php 7<!--編集番号指定用フォーム--> 8<form method="post"> 9 <label for="H_no" >編集対象番号(半角)</label> 10 <input type="namber" name="H_no" id="H_no" required="required"> 11 <input type="submit" value="編集"> 12 <?php echo $hMessage; ?> 13</form>

全体は以下です。

php

1<?php 2$fname = "keijiban.txt"; //保存するファイル 3$name = filter_input( INPUT_POST, "name" ); //投稿者の名前 4$comment = filter_input( INPUT_POST, "comment" ); //投稿するコメント 5$D_no = filter_input( INPUT_POST, "D_no" ); //削除番号の変数定義 6$H_no = filter_input( INPUT_POST, "H_no" ); //編集番号の定義 7$hidden = filter_input( INPUT_POST, "hidden" ); //hiddenの送信 8$psw = filter_input( INPUT_POST, "psw" ); //passwordの送信 9$chpsw = filter_input( INPUT_POST, "chpsw" ); //照合するパスワード 10$date = date( "Y-m-d H:i" ); //投稿日時 11$delimiter = "<>"; //区切り文字 12$search = array( "\r\n", "\r", "\n", "<>" ); //置き換え時の検索文字 13$replace = array( "<<改行1>>", "<<改行2>>", "<<改行3>>", "&lt;&gt;" ); //置き換える文字 14//投稿番号の定義 15$rname = str_replace( $search, $replace, $name ); //置き換えられた名前 16$rcomment = str_replace( $search, $replace, $comment ); //置き換えられたコメント 17if ( is_file( $fname ) ) { //ファイルの存在確認。 18 //最後の行にプラス1 19 $rows = file( $fname ); 20 $lastline = $rows[ count( $rows ) - 1 ]; 21 $num = explode( $delimiter, $lastline ); 22 $lastnum = $num[ 0 ] + 1; 23} else { //ファイルが無かった場合変数の定義を1とする 24 $lastnum = 1; 25} 26//書き込み内容 27$hozon = implode( $delimiter, array( $lastnum, $rname, $rcomment, $date, $psw ) ); 28 29//投稿部分 30if ( !empty( $name ) && !empty( $comment ) && !empty( $psw ) && empty( $hidden ) ) { //もし名前とコメントが送信されたら 31 $fp = fopen( $fname, "a" ); //追記モードでファイルを開く 32 if ( flock( $fp, LOCK_EX ) ) { //ロックする 33 fwrite( $fp, $hozon . "\r\n" ); //指定したファイルに追記モードで書き込み 34 } 35 flock( $fp, LOCK_UN ); 36 fclose( $fp ); 37 header( 'Location: keijiban.php', true, 303 ); 38 exit; 39} 40 41//編集番号指定 42elseif ( !empty( $H_no ) ) { //もしPOSTで編集用の番号が送信されたら 43 $rows = file( $fname ); //ファイルを配列として読み込む 44 foreach ( $rows as $row ) { //ループ 45 $ex = explode( $delimiter, $row ); //<>で分割し投稿番号取り出す 46if ( $H_no == $ex[ 0 ] ) { //送信と書き込みの番号が同じなら 47 $h_no = $ex[ 0 ]; 48 $h_name = $ex[ 1 ]; 49 $h_comment = $ex[ 2 ]; 50 $hMessage = ""; 51 } 52 if ( !in_array( $H_no, $ex, true )|| empty( $ex ) ) { //投稿番号の中に送信された番号がないか、ファイルの中身が無い時 53 $hMessage = "該当する投稿がありません"; 54 var_dump($H_no); 55var_dump($ex); 56var_dump($h_no); 57 }else{ 58 $hMessage = ""; 59 } 60 } 61 } 62 63 64//編集機能 65elseif ( !empty( $name ) && !empty( $comment ) && !empty( $hidden ) ) { //名前とコメントとhiddenが空でなかったら 66 $rows = file( $fname ); //ファイルを配列として読み込む 67 $fp = fopen( $fname, "w" ); //書き込みモードでファイルを開く 68 if ( flock( $fp, LOCK_EX ) ) { //排他ロック出来たら 69 foreach ( $rows as $row ) { //ループ 70 $ex = explode( $delimiter, trim( $row ) ); //<>で分割し投稿番号取り出す 71 if ( $hidden == $ex[ 0 ] && $chpsw !== $ex[ 4 ] ) { 72 $hpMessage = "パスワードが違います"; 73 $h_no = ""; 74 $h_name = ""; 75 $h_comment = ""; 76 $hMessage = ""; 77 } 78 79 if ( $hidden == $ex[ 0 ] && $chpsw == $ex[ 4 ] ) { //送信と書き込みの番号が同じで、且つパスワードが一致すけば 80 $hensyu = implode( $delimiter, array( $hidden, $rname, $rcomment, $date, $chpsw ) ); 81 fwrite( $fp, $hensyu . "\r\n" ); //指定したファイルに追記モードで書き込み 82 } else { 83 fwrite( $fp, $row ); 84 } 85 86 } 87 } 88 flock( $fp, LOCK_UN ); //ロック開放 89 fclose( $fp ); 90} 91 92//削除機能 93elseif ( !empty( $D_no ) && !empty( $chpsw ) ) { //削除番号とパスワードがからでなかったら 94 $rows = file( $fname ); //ファイルを配列として読み込む 95 $fp = fopen( $fname, "w" ); //wモードで開く 96 if ( flock( $fp, LOCK_EX ) ) { //もし排他ロックかけたら 97 foreach ( $rows as $row ) { //ループ 98 $ex = explode( $delimiter, trim( $row ) ); //<>で分割し投稿番号取り出す 99 if ( $D_no == $ex[ 0 ] && $chpsw == $ex[ 4 ] ) { //削除番号とパスワードが一致するものはなにもしない 100 $sMessage = "削除されました"; 101 } else { //それ以外は 102 fwrite( $fp, $row ); //ファイルに書きこむ 103 } 104 if ( !in_array( $D_no, $ex, true ) || empty( $ex ) ) { //投稿番号の中に送信された番号がなかった時 105 $sMessage = "該当する投稿がありません"; 106 } 107 if ( $D_no == $ex[ 0 ] && $chpsw !== $ex[ 4 ] ) { 108 $sMessage = "パスワードが違います"; 109 } 110 } 111 } 112 flock( $fp, LOCK_UN ); //ロック開放 113 fclose( $fp ); 114} 115 116?> 117<!doctype html> 118<html lang="ja"> 119<head> 120<meta charset="utf-8"> 121<title>簡易掲示板</title> 122<script> 123window.addEventListener('DOMContentLoaded', function(){ 124document.querySelector('#delbtn').addEventListener('click',function(e){ 125if(!confirm('本当に削除しますか?')){ 126alert('キャンセルされました'); 127e.preventDefault(); 128} 129}); 130}); 131</script> 132<style> 133span { 134 color : red; 135} 136</style> 137</head> 138<body> 139<?php 140$fname = "keijiban.txt"; 141$search = array( "<<改行1>>", "<<改行2>>", "<<改行3>>", "&lt;&gt;", ); //置き換え時の検索文字 142$replace = array( "\r\n", "\r", "\n", "<>", ); //置き換える文字 143//XSS対策 144function h( $str ) { 145 return nl2br(htmlspecialchars( $str, ENT_QUOTES, 'UTF-8' )) ; 146} 147$h_n = str_replace( $search, $replace, $h_name ); 148$h_c = str_replace( $search, $replace, $h_comment) ; 149 150if ( !empty( $H_no ) && $H_no == $h_no ) { 151 echo "<span>" . $h_no . "番</span>の投稿を編集をします<BR>"; 152} 153?> 154<!--投稿フォーム--> 155<form method="post" > 156 <label for="name-field">お名前<span>【必須】</span> </label> 157 <input type="hidden" name="hidden" value="<? echo $h_no; ?>"> 158 <input type="text" name="name" id="name-field" required="required" value="<?php echo $h_n ; ?>"> 159 <br> 160 <label for="comment">コメント<span>【必須】</span></label> 161 <textarea name="comment" cols="30" rows="3" id="comment" required="required"><?php echo $h_c ;?></textarea> 162 <br> 163 <?php 164 if ( !empty( $H_no ) ) { 165 echo "投稿時設定したパスワードを入力して下さい<span>【必須】</span><input type='password' name='chpsw' required='required'>"; 166 } else { 167 echo "<label for='psw' >パスワード設定</label><span>【必須】</span> 168 <input type='password' name='psw' required='required'>"; 169 } 170 ?> 171 <input type="submit" value="<?php if (!empty( $H_no ) ){ echo '編集'; }else{ echo '投稿'; } ?>"> 172 <?php echo $hpMessage;?> 173</form> 174<!--削除番号指定用フォーム--> 175<form method="post" name="sakujo"> 176 <label for="D_no" >削除対象番号(半角)</label> 177 <input type="namber" name="D_no" id="D_no" required="required"> 178 <br> 179 <label for="spsw" >削除パスワード</label> 180 <input type="password" name="chpsw" required="required"> 181 <input name="btn" type="submit" value="削除" id="delbtn"> 182 <?php echo $sMessage; ?> 183</form> 184 185<!--編集番号指定用フォーム--> 186<form method="post"> 187 <label for="H_no" >編集対象番号(半角)</label> 188 <input type="namber" name="H_no" id="H_no" required="required"> 189 <input type="submit" value="編集"> 190 <?php echo $hMessage; ?> 191</form> 192<?php 193//投稿一覧 194if ( !empty( $fname ) ) { 195 $rows = file( $fname ); 196 foreach ( $rows as $row ) { 197 $c = explode( $delimiter, $row ); 198 $c = str_replace( $search, $replace, $c ); 199 echo h( $c[ 0 ] ) . "<br>"; 200 echo h( $c[ 1 ] ) . "<br>"; 201 echo h( $c[ 2 ] ) . "<br>"; 202 echo h( $c[ 3 ] ) . "<br>"; 203 204 } 205} else { 206 echo "<p>投稿はまだありません</p>"; 207} 208var_dump( $h_name ); 209var_dump( h( $c[ 2 ] ) ); 210 211 212?> 213</body> 214</html> 215

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2019/10/11 10:11

「うまくいかなくなってしまいました。」なにがどうなってる? 具体的に示してくれないと的確な回答に繋がりません。
MakotoIshizawa

2019/10/11 10:19

すみません。 具体的には、投稿内に送信した番号があるときにも「該当する投稿がありません」と表示されてしまいます。 コードで言うと、 $exの中に$H_noがあるのに$hMesaageがechoされます。
guest

回答1

0

ベストアンサー

if ( !in_array( $D_no, $ex, true ) || empty( $ex ) ) { //投稿番号の中に送信された番号がなかった時 $sMessage = "該当する投稿がありません"; }

この処理、何をしようとしているか説明できますか?

$exは投稿データ1行分がデリミタで分解されたものは格納されている配列ですが、
その配列の中をin_array()で検索することって妥当でしょうか。
わたしはNOだと思います。
掲示板投稿の名前もしくはコメントに投稿番号とみなせる数字が書かれていたらヒットしてしまいかねません。
(仮に、ファイルに保存されている投稿データから、投稿番号だけ洗い出したものを配列の保持しているのであれば、in_array()を使う目もあるかもしれませんが、同時にパスワードも検証するとなるとやはり破綻しかねません。)

そこにさらにempty( $ex )って、この処理の流れの中で成り立たないことではないでしょうか。

あくまで一例ですが、
foreach()ループの外側でフラグ変数を宣言しておいてfalseで初期化しておいて、
foreach()ループ内で投稿番号とパスワードがもしも一致したならば、そのフラグ変数をtrueにするようにしておけば、
foreach()ループを抜けた時点でもfalseであれば一致するものがなかったと判断できます。

投稿2019/10/11 10:20

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

MakotoIshizawa

2019/10/11 10:29

ありがとうございます。 $exの中身の件、考えが浅はかでした。 フラグ変数というのが初耳で理解が追いついていないですが、調べてなんとか試してみます。
MakotoIshizawa

2019/10/14 06:28

ありがとうございました。 うまくいきました。 フラグというやり方を知ってちょっとだけ幅が広がりました。 勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問