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

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

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

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

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

1回答

8218閲覧

php簡易掲示板に特定の番号だけを削除する削除機能をつけたい

hkr.0921

総合スコア2

PHP

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

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

1クリップ

投稿2020/08/30 04:11

編集2020/08/30 04:36

前提・実現したいこと

phpで簡易掲示板に「削除機能」を付加し、指定された番号の投稿だけ削除できるようにしたいです。
削除番号指定用フォームを追加→ファイル読み込み関数でファイルの中身を1行1要素として配列変数に代入→ファイルを開き、先ほどの配列の要素数(=行数)だけループさせるところまでは調べて書き込むことができたのですが、"ループ処理内で投稿番号と削除対象番号を比較し、等しくない場合は、ファイルに追加書き込みを行う"の部分がわからず、実装出来ません。
初歩的な質問ではあると思いますがご教授お願いします。

該当のソースコード

PHP

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <title>簡易掲示板</title> 6</head> 7<body> 8 <form action="" method="post"> 9 <!--名前の入力フォーム--> 10 <input type="text" name="name" value="名前"> 11 <!--コメントの入力フォーム--> 12 <input type="text" name="comment" value="コメント"> 13 <input type="submit" name="submit"> 14 <!--消去の入力フォーム--> 15 <input type="text" name="deleteno" value=""> 16 <input type="submit" name="delete" value="削除"> 17 </form> 18 <?php 19 /*ファイルの指定*/ 20 $filename = "mission_3-1.txt"; 21 /*POST送信があったとき*/ 22 if(isset($_POST["delete"])){ 23 /*変数に代入*/ 24 $delete = $_POST["deleteno"]; 25 /*ファイル全体を読み込んで配列に格納する*/ 26 $delCon = file("mission_3-1.txt"); 27 /*配列の要素数(=行数)だけループさせる*/ 28 for ($j = 0; $j < count($delCon) ; $j++){ 29 /*区切り文字「<>」で分割して、投稿番号を取得*/ 30 $delData = explode("<>", $delCon[$j]); 31 /*投稿番号と削除対象番号を比較。等しくない場合はファイルに追加書き込みを行う*/ 32 if ($delData[0] == $delete) { 33 array_splice($delcon, $j, 1); 34 file_put_contents($filename, implode("\n", $delCon)); 35 } 36 37 } 38 fclose($fp); 39 } 40 /*POST送信があった時*/ 41 if (isset($_POST["submit"])){ 42 /*変数に代入*/ 43 $name = $_POST["name"]; 44 $comment = $_POST["comment"]; 45 /*日付データ取得*/ 46 $date = date("Y/m/d H:i:s"); 47 /*ファイルの存在がある場合は投稿番号+1、なかったら1を指定*/ 48 if (file_exists($filename)) { 49 $num = count(file($filename))+1; 50 } else { 51 $num = 1; 52 } 53 /*書き込む文字列を組み合わせた変数*/ 54 $data = "$num <> $name <> $comment <> $date". PHP_EOL; 55 $fp2 = fopen($filename , "a"); 56 fwrite( $fp2 , $data); 57 fclose($fp2); 58 } 59 ?> 60 61 【 投稿一覧 】<br> 62 63 <?php 64 /*ファイル全体を読み込んで配列に格納する*/ 65 $ret_array = file( $filename ); 66 if(file_exists($filename)){ 67 foreach( $ret_array as $value ) { 68 $result = explode("<>", $value); 69 echo "$result[0] $result[1] $result[2] $result[3] <br>" ; 70 } 71 } 72 73 ?> 74</body> 75</html>

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2020/09/02 01:19

m6uさんがご指摘されてるとおり、いくつか問題がありますし、多分まだ指摘できるところがあるけど言ってない部分もあると思います。が、プログラムは動かないと面白くないので、まずは細かいところは端折って動くように考えましょう。 ■指定番号の削除ってどう実現すればいいの? 恐らく質問者さんが分からないのはココでしょう。何か文章で実現方法を聞いたのでしょうが、それがイマイチ納得できていないのだと思います。 今は 1 <> ほげ <> ふが <> 2020/09/02 10:03:07 2 <> ふが <> ぴよ <> 2020/09/02 10:03:24 のような形で記録されているmission_3-1.txtですが、これをどうやったら、例えば1の投稿を削除できるのでしょうか?現在2件しかない状態なので、ファイルの内容が 2 <> ふが <> ぴよ <> 2020/09/02 10:03:24 こうなったら、1行目を削除したことになります。当たり前ですよね。 今回はどうやってそれを実現するかというと、、、 元のファイル内容を丸ごと読み込んで、「書き込むときに、1行目の内容だけ書き込まないようにする」 という方式です。普通は、1行目を書き込んで、2行目を書き込んで、、、という形でループするのですが、1行目のときはスキップして、2行目を書き込む、、、という形でループするのです。そして、1行目をスキップする方法が、、、 /*投稿番号と削除対象番号を比較。等しくない場合はファイルに追加書き込みを行う*/ if ($delData[0] == $delete) { array_splice($delcon, $j, 1); file_put_contents($filename, implode("\n", $delCon)); } まあこのままだと、意図したとおりに動いたとしても、投稿番号と削除番号が等しいときだけ、ファイルに書き込もうとしているので、今回の例だと1行目だけ書き込もうとして、2行目をスキップしちゃうので、逆の動作になってしまいますが。。。 まずは if ($delData[0] == $delete) { ではなく if ($delData[0] != $delete) { でないとダメですよね。これだけではまだ思ったとおりに動かないですが、いっぺんに理解しようとせず、1つずつ理解していけばいいので、気長に頑張ってください。 次のヒントは「$delData[0]に余計な空白がないか」です。
guest

回答1

0

ベストアンサー

削除処理のところをピックアップしてみます。

php

1 /*POST送信があったとき*/ 2 if (isset($_POST["delete"])) { 3 /*変数に代入*/ 4 $delete = $_POST["deleteno"]; 5 /*ファイル全体を読み込んで配列に格納する*/ 6 $delCon = file("mission_3-1.txt"); 7 /*配列の要素数(=行数)だけループさせる*/ 8 for ($j = 0; $j < count($delCon) ; $j++){ 9 /*区切り文字「<>」で分割して、投稿番号を取得*/ 10 $delData = explode("<>", $delCon[$j]); 11 /*投稿番号と削除対象番号を比較。等しくない場合はファイルに追加書き込みを行う*/ 12 if ($delData[0] == $delete) { 13 array_splice($delcon, $j, 1); 14 file_put_contents($filename, implode("\n", $delCon)); 15 } 16 } 17 fclose($fp); 18 } 19

file_put_contents()implode()で連結したものをファイルに書き出しているようですが、
書き出したあとのファイルの中身を確認していますか?

書き出しの処理のところで

php

1 /*書き込む文字列を組み合わせた変数*/ 2 $data = "$num <> $name <> $comment <> $date". PHP_EOL;

としていてPHP_EOLを使っているのに、
implode()でなぜ"\n"を使うのでしょう?
ふつうは、同じ改行コードにしますよね。
結果が同じだったらどう表記してもいいという考えでしょうか。

そして、
implode()で投稿データの再連結をしていますが、
一番最後のデータの後ろに"\n"はつくのかなぁ。
丁寧に、投稿データの加工のそれぞれの場面で、
var_dump()とか駆使しながら、狙った通りのデータの持ち方になっているかを
しっかり確認してください。
思い込みを排除して冷静に丁寧に。

あと、削除の動作についてですが、
投稿番号が一致したら削除ですよね、
投稿データをひとつ削除して書き出すので物理削除します。
例えば1,2,3,4,5の投稿があって、4を削除すると、
ファイル上には1,2,3,5があります。
データ数を$num = count(file($filename))+1;にて求めると「5」が使われてしまいます。
簡単に投稿番号の重複を呼び起こします。

重複を起こさないためには、

a)
面倒でも投稿データをひとつひとつチェックして、
投稿番号の最大値を求め、+1して使う。

b)
投稿データファイルとば別に
投稿番号のみを管理するファイルを設け、
投稿を書き込むたびに+1した内容に更新する。

などといった方法が考えられます。

投稿データの書き込みの箇所でもう一点。

php

1 /*書き込む文字列を組み合わせた変数*/ 2 $data = "$num <> $name <> $comment <> $date". PHP_EOL;

こんな連結方法でいいのでしょうか?
分離方法が

php

1$result = explode("<>", $value);

となっているので、どちらかに統一しないと、
前後に余計に空白がついたデータが使われます。
HTML上に出力したソースコードで意図せず空白が前後についていると思われます。
揃えるなら例えば

php

1$result = explode(" <> ", $value);

とするか、そもそも連結箇所を

php

1 /*書き込む文字列を組み合わせた変数*/ 2 $data = implode("<>", [$num, $name, $comment, $date]) . PHP_EOL;

などとするかです。

まぁ、それを言い出すと、
フォームで投稿文字列に「<>」が入っている場合の対策がないことも気になります。
$nameや$commentに当たる箇所に「<>」が入っていると、
ファイルから読み出して分離するときに投稿データに含まれる「<>」で区切られると
おかしなことになります。

投稿2020/08/30 06:34

編集2020/08/30 06:46
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問