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

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

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

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

Q&A

解決済

2回答

3821閲覧

簡易掲示板で1行だけ上書きする方法がわかりません。

KZKKZ_ZKY

総合スコア5

PHP

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

0グッド

0クリップ

投稿2019/08/24 05:33

PHP

1<!DOCTYPE html> 2<html lang="en" dir="ltr"> 3 <head> 4 <meta charset="utf-8"> 5 <title>簡易掲示板</title> 6 </head> 7 <body> 8 9 <?php 10 $filename = "mission_3-1.txt"; 11 12 if(!empty($_POST["edit"])){ 13 14 $editline = file($filename); 15 $edit = $_POST["edit"]; 16 17 foreach($editline as $ccc){ 18 $data3 = explode(" ",$ccc); 19 if($data3[0] == $edit){ 20 $namae_e = $data3[1]; 21 $message_e = $data3[2]; 22 } 23 } 24 } 25 ?> 26 <!--投稿フォーム--> 27 <form action="mission_3-4.php" method="post"> 28 29 <!--編集番号--> 30 <input type="text" name="number" value="<?php 31 if(!empty($_POST["edit"])){ 32 echo $edit; 33 } ?>"> 34 35 <!--上書き--> 36 <?php 37 $filename = "mission_3-1.txt"; 38 39 if(!empty($_POST["edit"])){ 40 41 $editline2 = file($filename); 42 $edit2 = $_POST["edit"]; 43 $fp4 = fopen($filename, "a" ); 44 45 foreach($editline2 as $ddd){ 46 $data4 = explode(" ",$ddd); 47 if($data4[0] == $edit2){ 48 //上書き内容 49 }else{ 50 //他の文をそのまま出す 51 } 52 } 53 fclose( $fp4 ); 54 } 55 ?> 56 57 <p>名前: 58 <input type="text" name="name" value="<?php 59 if(!empty($_POST["edit"])){ 60 echo $namae_e; 61 } ?>"></p> 62 63 <p>投稿内容:<textarea name="comment"><?php if(!empty($_POST["edit"])){ 64 echo $message_e; 65 }?></textarea></p> 66 67 <button type = "submit">送信</button> 68 69 </form> 70 <br> 71 72 <!--削除フォーム--> 73 <form action="mission_3-4.php" method="post"> 74 <p>投稿番号:<input type="text" name="delete"></p> 75 <button type = "submit">削除</button> 76 </form> 77 <br> 78 79 <!--編集フォーム--> 80 <form action="mission_3-4.php" method="post"> 81 <p>投稿番号:<input type="text" name="edit"></p> 82 <button type = "submit">編集</button> 83 </form> 84 85 <?php 86 87 $date = date("Y/m/d H:i:s"); 88 $filename = "mission_3-1.txt"; 89 //$count = count( file($filename) ); 90 91 if(!empty($_POST["name"])&&!empty($_POST["comment"])){ 92 93 $namae = $_POST["name"]; 94 $message = $_POST["comment"]; 95 96 $toukou = (sizeof(file($filename))+1)."<>".$namae."<>".$message."<>".$date; 97 98 $fp = fopen($filename, "a" ); 99 $keijiban = explode("<>",$toukou); 100 $string = implode(" ",$keijiban); 101 102 fwrite( $fp , "$string\r\n" ); 103 fclose( $fp ); 104 105 }elseif(!empty($_POST["delete"])){ 106 107 $delline = file($filename); 108 $delete = $_POST["delete"]; 109 $fp2 = fopen($filename,"w"); 110 fclose( $fp2 ); 111 $fp3 = fopen($filename,"a"); 112 113 if(!empty($filename)){ 114 foreach($delline as $bbb){ 115 $data2 = explode(" ",$bbb); 116 if($data2[0] !== $delete){ 117 fwrite( $fp3 , $bbb ); 118 } 119 } 120 } 121 fclose( $fp3 ); 122 } 123 124 $ret_array = file($filename); 125 foreach($ret_array as $aaa){ 126 echo $aaa; 127 echo "<br>"; 128 } 129 130 ?> 131 132 </body> 133 134</html>

以上が現在のコードとなっています。
色々な質問を見て回ったのですがわからなかったため質問させていただきます。

今のコードでは、編集フォームに番号を入力すると、その番号のものを入力フォームに表示させるところまでできています。

編集番号を受け取ったときにその編集番号を表示させる場所も設けており、そこに番号が入っているときに、その番号と同じ投稿番号の1文を上書きしたいと思っています。

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

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

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

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

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

guest

回答2

0

ベストアンサー

まずはPHP云々の前に、フォームとそれによって送られるパラメータについて一旦整理した方が良い気がします。

PHPはHTMLと混在して記述できるのでどうしても今回のようにコードを切れ切れに入れてしまいがちですが、あまり混在させすぎると可読性と記述ミスにもつながりやすいので、できるだけパートを分けて書いた方が良いかと思います。

まずHTMLを整理すると(一部修正しています)

HTML

1<!DOCTYPE html> 2<html lang="ja" dir="ltr"> 3 <head> 4 <meta charset="utf-8"> 5 <title>簡易掲示板</title> 6 </head> 7 <body> 8 <!--投稿フォーム--> 9 <form action="mission_3-4.php" method="post"> 10 <!--編集番号--> 11 <input type="text" name="number" value=""> 12 <p>名前:<input type="text" name="name" value=""></p> 13 <p>投稿内容:<textarea name="comment"></textarea></p> 14 <button type="submit">送信</button> 15 </form> 16 <br> 17 18 <!--削除フォーム--> 19 <form action="mission_3-4.php" method="post"> 20 <p>投稿番号:<input type="text" name="delete"></p> 21 <button type="submit">削除</button> 22 </form> 23 <br> 24 25 <!--編集フォーム--> 26 <form action="mission_3-4.php" method="post"> 27 <p>投稿番号:<input type="text" name="edit"></p> 28 <button type="submit">編集</button> 29 </form> 30 </body> 31</html> 32

という形になるかと思います。
このフォームからわかるのは、投稿フォームでsubmitして送られるのは
(コロンの左側がname、右側が入っている値です)

number : 編集番号
name : 名前
comment : 投稿内容

の3つです。
次に、削除フォームでは

delete : 投稿番号

同様に編集フォームでは

edit : 投稿番号

となっています。
次に、PHP部分だけを抜き出してみると

PHP

1<?php 2 // データファイル名の定義 3 $filename = "mission_3-1.txt"; 4 5 // 編集モードの場合はデータファイルを開き内容を取得する 6 if(!empty($_POST["edit"])){ 7 8 $editline = file($filename); 9 $edit = $_POST["edit"]; 10 11 foreach($editline as $ccc){ 12 $data3 = explode("<>",$ccc); 13 if($data3[0] == $edit){ 14 $namae_e = $data3[1]; 15 $message_e = $data3[2]; 16 } 17 } 18 } 19 20 // numberのvalueにセット 21 if(!empty($_POST["edit"])){ 22 echo $edit; 23 } 24 25 // 上書き 26 $filename = "mission_3-1.txt"; 27 28 if(!empty($_POST["edit"])){ 29 30 $editline2 = file($filename); 31 $edit2 = $_POST["edit"]; 32 $fp4 = fopen($filename, "a" ); 33 34 foreach($editline2 as $ddd){ 35 $data4 = explode(" ",$ddd); 36 if($data4[0] == $edit2){ 37 //上書き内容 38 }else{ 39 //他の文をそのまま出す 40 } 41 } 42 fclose( $fp4 ); 43 } 44 45 // nameのvalueにセット 46 if(!empty($_POST["edit"])){ 47 echo $namae_e; 48 } 49 50 // commentのvalueにセット 51 if(!empty($_POST["edit"])){ 52 echo $message_e; 53 } 54 55 // 必要変数のセット 56 $date = date("Y/m/d H:i:s"); 57 $filename = "mission_3-1.txt"; 58 59 // 投稿モード、削除モードによって処理を分岐 60 61 // 投稿モードの場合 62 if(!empty($_POST["name"]) && !empty($_POST["comment"])){ 63 64 $namae = $_POST["name"]; 65 $message = $_POST["comment"]; 66 67 $toukou = (sizeof(file($filename))+1)."<>".$namae."<>".$message."<>".$date; 68 69 $fp = fopen($filename, "a" ); 70 $keijiban = explode("<>",$toukou); 71 $string = implode(" ",$keijiban); 72 73 fwrite( $fp , "$string\r\n" ); 74 fclose( $fp ); 75 76 } 77 // 削除モードの場合 78 elseif(!empty($_POST["delete"])){ 79 80 $delline = file($filename); 81 $delete = $_POST["delete"]; 82 $fp2 = fopen($filename,"w"); 83 fclose( $fp2 ); 84 $fp3 = fopen($filename,"a"); 85 86 if(!empty($filename)){ 87 foreach($delline as $bbb){ 88 $data2 = explode(" ",$bbb); 89 if($data2[0] !== $delete){ 90 fwrite( $fp3 , $bbb ); 91 } 92 } 93 } 94 fclose( $fp3 ); 95 } 96 97 // ファイルの内容を出力(デバッグ用?) 98 $ret_array = file($filename); 99 foreach($ret_array as $aaa){ 100 echo $aaa; 101 echo "<br>"; 102 } 103?> 104

となっていて、受け渡されるデータと処理に少し齟齬があるように見えます。
(一部2か所で同じ値がセットされている変数があるのも気になりますが…それは今回の質問には関係ないのでスルーします)

まず、投稿フォームにはname、comment、numberという3つの値がありますが、このうち「number」は新規登録の場合ここには何も入力されておらず、更新の場合のみ自動的に番号がセットされる…という動作を想定していると考え、それを踏まえて、処理分岐の条件を整理すると

◆新規追加
nameとcommentが入力されていて、かつnumberに値が入力されていない

◆更新(上書き)処理
nameとcommentが入力されていて、かつnumberに値が入力されている

となります。
となると中央部に書かれている「上書き」処理は下の投稿、削除の分岐の所に統合した方が良さそう…となりますよね

つまり

PHP

1if(!empty($_POST["name"]) && !empty($_POST["comment"])){ 2 // 更新モード 3 if(!empty($_POST["number"])){ 4 // 更新処理を書く 5 } 6 // 新規追加モード 7 else{ 8 // 新規追加処理を書く 9 } 10} 11// 削除モードの場合 12elseif(!empty($_POST["delete"])){ 13 // 削除処理を書く 14}

という感じで処理を分岐していけばよいかと思います。

※全体的にPHP部分を1か所にまとめ、フォーム中にセットする値は$name等の変数のセットしておいて、それをHTML中に埋め込む方が可読性も上がるので良いと思います。


すみません、1行だけ変更する方法…って質問でしたね。肝心なその部分の処理を書いてませんでしたので追記です。

単純に、データを取得する時と同じ処理の途中で、numberと一致しているかどうかをチェックし、そこだけ書き出し方を変えています。
なお、勉強用の簡易掲示板という事ですのでロック処理等はあえて書いてないですが、実際に掲示板として機能させようとした場合には、排他ロック等の処理が必要になりますので、一旦予定していた動作確認が取れたらそういった処理を追加していけばよいと思います。

PHP

1$date = date("Y/m/d H:i:s"); 2$delimiter = "<>"; 3 4if(!empty($_POST["name"]) && !empty($_POST["comment"])){ 5 $namae = $_POST["name"]; 6 $message = $_POST["comment"]; 7 8 if(!empty($_POST["number"]){ 9 $lines = file($filename); 10 $number = $_POST["number"]; 11 12 $fp = fopen($filename, "w" ); 13 14 foreach($lines as $current_line){ 15 $posted_data = explode(" ",$current_line); 16 17 if($posted_data[0] == $number){ 18 $update_line = implode( $delimiter, array( $number, $name, $message, $date) ); 19 fwrite( $fp, "$update_line\r\n"); 20 } else{ 21 fwrite( $fp, "$current_line\r\n"); 22 } 23 } 24 25 fclose($fp); 26 } else{ 27 // 新規追加処理 28 } 29} 30

あと、あちこちからコピペして作られてるのかと思いますが、データファイルに保存時にデータを連結しているデリミタと、explodeしているときのデリミタが異なっているので多分データが正しく保存されていません。
できれば、今回のデリミタ等、プログラム中で何度も出てくる文字列は定数(変数)として最初に定義しておいてそれを使う方がバグが出にくくなります。

投稿2019/08/27 04:05

編集2019/08/27 04:52
45_Shingo

総合スコア177

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

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

KZKKZ_ZKY

2019/08/27 14:35

ここまでしっかりと説明をいただけると思っていなかったので、うれしくて涙が出てきました…。 写すのではなく、全て理解したうえで課題に取り組もうと思います。 この度は本当にありがとうございます。
guest

0

考え方は 「上書きする」というより「置き換える」 ですね。
deleteと流れは似ています。
deleteの場合は「同じ番号以外を保存する」ですが
updateの場合は「同じ番号は入力値、違う番号はそのまま保存」です。

投稿2019/08/24 05:46

m.ts10806

総合スコア80850

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問