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

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

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

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

Q&A

解決済

1回答

4325閲覧

PHP 簡易的な掲示板で、テキストファイルの編集について

Nobuyasu

総合スコア12

PHP

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

0グッド

0クリップ

投稿2017/02/14 14:36

編集2017/02/15 03:03

phpファイルとは別に、テキストファイルを同じディレクトリに作っています。
削除までは問題なく動作しましたが、編集機能(keijiban.txtから投稿番号を、編集番号としてPOSTでそれぞれ取得したものを比較して一致したときargs[2]に編集内容をPOSTしたコメントを上書き、file_put_contentsでテキストファイルに上書き)を作成したのですが、編集ボタンを押すと投稿が1〜3個しか表示されなくなりました。また再読み込みをすると同じ現象が起きます。

どこをどのように書き換えるべきでしょうか。アドバイスをよろしくお願いします。

今度こそソースコードをバッククオートで囲みました。度々申し訳ございません。

<!DOCTYPE html> 
 <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>掲示板</title> </head> <body> <form action=keijiban.php method="post"> 名前:<br /> <input type="text" name="name" size="30" value="" /><br /> コメント:<br /> <textarea name="comment" cols="30" rows="5"></textarea><br /> <br /> <input type="submit" value=“投稿” /> <br /> <br /> 削除する投稿番号: <input type="number" name= "delete" value=""><br /> 編集する投稿番号: <input type="number" name= "change" value=""><br /> 編集内容:<br /> <textarea name="change_comment" cols="30" rows="5"></textarea><br /> <input type="submit" value=“編集” /> <br /> <br /> <br /> <br /> </form> <?php function dispKekka($var, $var_kata){ print('変数に格納されている値は'.$var.'です<br>'); print('変数の型は'.$var_kata.'です<br><br>'); } function comment_change($change_number,$change_comment){ $array = file("keijiban.txt"); for($num = 0; $num < count($array); ++$num){; $args = explode("<>",$array[$num]); if( "{".$change_number."}" == $args[0]){ $args[2] = "{".$_POST["change_comment"]."}"; return $args[2]; } } } $fpr = fopen("keijiban.txt","r"); for($num = 0;fgets($fpr);$num++); $num_ = $num+1; fclose($fpr); date_default_timezone_set('Japan'); if($num == 0){ if(isset($_POST["name"]) and isset($_POST["comment"])){ if($_POST["name"] != "" and $_POST["comment"]){ $fpw = fopen("keijiban.txt","w"); fwrite($fpw,"{1}"."<>{"); fwrite($fpw,$_POST["name"]."}<>{"); fwrite($fpw,$_POST["comment"]."}<>{"); fwrite($fpw,date('Y年m月d日 H時i分s秒')."}\n"); fclose($fpw); } } } else{ if(isset($_POST["name"]) and isset($_POST["comment"])){ if($_POST["name"] != "" and $_POST["comment"]){ $fpa = fopen("keijiban.txt","a"); fwrite($fpa,"{".$num_."}<>{"); fwrite($fpa,$_POST["name"]."}<>{"); fwrite($fpa,$_POST["comment"]."}<>{"); fwrite($fpa,date('Y年m月d日 H時i分s秒')."}\n"); fclose($fpa); } } } if(isset($_POST["delete"]) and $_POST["delete"] != ""){ echo("削除する投稿番号が入力されました。".$_POST["delete"]."<br />\n"); $del = intval($_POST["delete"]) - 1; $file = file('keijiban.txt'); unset($file[$del]); file_put_contents('keijiban.txt', $file); } $file = "keijiban.txt"; $array = file($file); for($num = 0; $num < count($array); ++$num){ $args = explode("<>",$array[$num]); $new_num = $num + 1; $array = file($file); $args[0] = "{".$new_num."}"; if($_POST["change"] != ""){ if("{".$_POST["change"]."}" == $args[0]){ $args[2] = comment_change($_POST["change"],$_POST["change_comment"]); file_put_contents("keijiban.txt",$args); } } echo("投稿番号".$args[0]."<br />\n"); echo("投稿者".$args[1]."<br />\n"); echo("コメント".$args[2]."<br />\n"); echo("投稿日時".$args[3]."<br />\n<br />\n"); } ?> </body> </html>

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

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

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

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

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

kei344

2017/02/15 02:53

'''(カンマ3つ)ではなく ```(バッククオート3つ)です。記入エリアの右部分あたりにリアルタイムに結果が表示されていると思うので、そこを見ながら調整してください。
退会済みユーザー

退会済みユーザー

2017/02/15 03:05

バッククオートは、Shift+@ね。Shift+7じゃないよ。
guest

回答1

0

ベストアンサー

投稿番号の管理をどう捉えるか、整理したほうがいいかもしれません。

for($num = 0; $num < count($array); ++$num){でループを回す場合、
$numは0から始まり$array-1で終わりますが、
keijiban.txtに記録している投稿番号は削除すると歯抜けになるので、
$new_num = $num + 1;としてあと$args[0] = "{".$new_num."}";としているので、
ファイル上の投稿番号とズレます。

歯抜けさせないために番号を振り直すとすると、
誰かが画面を開きっぱなしにしている最中に他の人が投稿を削除すると、
例えば本来削除したい5番の投稿が実は他人によって既に4番になっていて、
6番がずれて5番になってしまっているのを削除してしまう、
みたいな挙動をします。

ループカウンタの$num由来で投稿番号を作らないようにして、
ファイルに記録してある投稿番号を改ざんしないようにするだけで、
動きそうな気がします。

あと細かいこととして、andとorは&&||の方がいいです。
使い方によっては意図しない挙動を誘発します。
PHP/andと&&など比較演算子の違い - TOBY SOFT wiki
PHPのand,or演算子の使い道を考えてみる | WEB EGG

さらに細かいこととして、
$args = explode("<>",$array[$num]);
list($post_num, $post_user, $post_comment, $post_date) = explode("<>", $array[$num]);
みたいにすると、可読性が高まって混乱を防げます。


ここはこうすると破壊せずに済むかもよ。

php

1 if($_POST["change"] != ""){ 2 if("{".$_POST["change"]."}" == $args[0]){ 3 $args[2] = comment_change($_POST["change"],$_POST["change_comment"]); 4 $array[$num] = implode("<>", $args); 5 file_put_contents("keijiban.txt",implode("", $array)); 6 } 7 }

投稿2017/02/15 03:19

編集2017/02/15 10:56
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

Nobuyasu

2017/02/15 04:01 編集

ありがとうございます。 投稿番号を$numとは関係ないようにしてみると期待している動きをしました。 ただ編集後に ``` file_put_contents("keijiban.txt",$args[2]);``` この動作を行なっているのですが、```file_put_contents```の書いている場所が悪いのか全てargs[0]の中に投稿番号・名前・コメント・日付が入ってしまいます。
退会済みユーザー

退会済みユーザー

2017/02/15 04:14 編集

file_put_contents()でファイルを$args[2]で破壊してますね。 しかし$arrayだとしても、$arrayの中身を書き換えないと意味がない。 $arrayの該当箇所を、もう一度編集し直してから、file_put_contents()しなおす。 投稿を表示する場面でコメント差し替えの動作が混ざっていてそこでファイルに書き出すのは 流れが良くないので、 投稿を表示するループの前にコメント差し替えブロックを置いたほうがいい。
退会済みユーザー

退会済みユーザー

2017/02/15 10:56

回答ズバリを待っているような気がしたので、一応デバッグしてみました。
Nobuyasu

2017/02/15 13:29

そういうわけではなかったのですが...汗 ありがとうございます!解決できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問