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

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

ただいまの
回答率

88.93%

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

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 968

KZKKZ_ZKY

score 5

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>簡易掲示板</title>
  </head>
  <body>

    <?php
      $filename = "mission_3-1.txt";

      if(!empty($_POST["edit"])){

        $editline = file($filename);
        $edit = $_POST["edit"];

        foreach($editline as $ccc){
          $data3 = explode(" ",$ccc);    
            if($data3[0] == $edit){
              $namae_e = $data3[1];
              $message_e = $data3[2];
            }
        }
      }
    ?>
    <!--投稿フォーム-->
    <form action="mission_3-4.php" method="post">

      <!--編集番号-->
      <input type="text" name="number" value="<?php
          if(!empty($_POST["edit"])){
            echo $edit;
          } ?>">

      <!--上書き-->
      <?php
        $filename = "mission_3-1.txt";

        if(!empty($_POST["edit"])){

          $editline2 = file($filename);
          $edit2 = $_POST["edit"];
          $fp4 = fopen($filename, "a" );

          foreach($editline2 as $ddd){
            $data4 = explode(" ",$ddd);
            if($data4[0] == $edit2){
              //上書き内容
            }else{
              //他の文をそのまま出す
            }
          }
          fclose( $fp4 );
        }
      ?>

      <p>名前:
        <input type="text" name="name" value="<?php
          if(!empty($_POST["edit"])){
            echo $namae_e;
          } ?>"></p>

      <p>投稿内容:<textarea name="comment"><?php if(!empty($_POST["edit"])){
        echo $message_e;
      }?></textarea></p>

      <button type = "submit">送信</button>

    </form>
    <br>

    <!--削除フォーム-->
    <form action="mission_3-4.php" method="post">
      <p>投稿番号:<input type="text" name="delete"></p>
      <button type = "submit">削除</button>
    </form>
    <br>

    <!--編集フォーム-->
    <form action="mission_3-4.php" method="post">
      <p>投稿番号:<input type="text" name="edit"></p>
      <button type = "submit">編集</button>
    </form>

    <?php

    $date = date("Y/m/d H:i:s");
    $filename = "mission_3-1.txt";
    //$count = count( file($filename) );

    if(!empty($_POST["name"])&&!empty($_POST["comment"])){

      $namae = $_POST["name"];
      $message = $_POST["comment"];

      $toukou = (sizeof(file($filename))+1)."<>".$namae."<>".$message."<>".$date;

      $fp = fopen($filename, "a" );
      $keijiban = explode("<>",$toukou);
      $string = implode(" ",$keijiban);

      fwrite( $fp , "$string\r\n" );
      fclose( $fp );

    }elseif(!empty($_POST["delete"])){

      $delline = file($filename);
      $delete = $_POST["delete"];
      $fp2 = fopen($filename,"w");
      fclose( $fp2 );
      $fp3 = fopen($filename,"a");

      if(!empty($filename)){
        foreach($delline as $bbb){
          $data2 = explode(" ",$bbb);    
            if($data2[0] !== $delete){
              fwrite( $fp3 , $bbb );
            }
        }
      }
      fclose( $fp3 );
    }

    $ret_array = file($filename); 
    foreach($ret_array as $aaa){
      echo $aaa;
      echo "<br>";
    }

    ?>

  </body>

</html>

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

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

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

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

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

<!DOCTYPE html>
<html lang="ja" dir="ltr">
    <head>
        <meta charset="utf-8">
        <title>簡易掲示板</title>
    </head>
    <body>
        <!--投稿フォーム-->
        <form action="mission_3-4.php" method="post">
            <!--編集番号-->
            <input type="text" name="number" value="">
            <p>名前:<input type="text" name="name" value=""></p>
            <p>投稿内容:<textarea name="comment"></textarea></p>
            <button type="submit">送信</button>
        </form>
        <br>

        <!--削除フォーム-->
        <form action="mission_3-4.php" method="post">
            <p>投稿番号:<input type="text" name="delete"></p>
            <button type="submit">削除</button>
        </form>
        <br>

        <!--編集フォーム-->
        <form action="mission_3-4.php" method="post">
            <p>投稿番号:<input type="text" name="edit"></p>
            <button type="submit">編集</button>
        </form>
    </body>
</html>


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

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

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

delete : 投稿番号

同様に編集フォームでは

edit : 投稿番号

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

<?php
    // データファイル名の定義
    $filename = "mission_3-1.txt";

    // 編集モードの場合はデータファイルを開き内容を取得する
    if(!empty($_POST["edit"])){

        $editline = file($filename);
        $edit = $_POST["edit"];

        foreach($editline as $ccc){
            $data3 = explode("<>",$ccc);        
                if($data3[0] == $edit){
                    $namae_e = $data3[1];
                    $message_e = $data3[2];
                }
        }
    }

    // numberのvalueにセット
    if(!empty($_POST["edit"])){
        echo $edit;
    }

    // 上書き
    $filename = "mission_3-1.txt";

    if(!empty($_POST["edit"])){

        $editline2 = file($filename);
        $edit2 = $_POST["edit"];
        $fp4 = fopen($filename, "a" );

        foreach($editline2 as $ddd){
            $data4 = explode(" ",$ddd);
            if($data4[0] == $edit2){
                //上書き内容
            }else{
                //他の文をそのまま出す
            }
        }
        fclose( $fp4 );
    }

    // nameのvalueにセット
    if(!empty($_POST["edit"])){
        echo $namae_e;
    }

    // commentのvalueにセット
    if(!empty($_POST["edit"])){
        echo $message_e;
    }

    // 必要変数のセット
    $date = date("Y/m/d H:i:s");
    $filename = "mission_3-1.txt";

    // 投稿モード、削除モードによって処理を分岐

    // 投稿モードの場合
    if(!empty($_POST["name"]) && !empty($_POST["comment"])){

        $namae = $_POST["name"];
        $message = $_POST["comment"];

        $toukou = (sizeof(file($filename))+1)."<>".$namae."<>".$message."<>".$date;

        $fp = fopen($filename, "a" );
        $keijiban = explode("<>",$toukou);
        $string = implode(" ",$keijiban);

        fwrite( $fp , "$string\r\n" );
        fclose( $fp );

    }
    // 削除モードの場合
    elseif(!empty($_POST["delete"])){

        $delline = file($filename);
        $delete = $_POST["delete"];
        $fp2 = fopen($filename,"w");
        fclose( $fp2 );
        $fp3 = fopen($filename,"a");

        if(!empty($filename)){
            foreach($delline as $bbb){
                $data2 = explode(" ",$bbb);        
                    if($data2[0] !== $delete){
                        fwrite( $fp3 , $bbb );
                    }
            }
        }
        fclose( $fp3 );
    }

    // ファイルの内容を出力(デバッグ用?)
    $ret_array = file($filename); 
    foreach($ret_array as $aaa){
        echo $aaa;
        echo "<br>";
    }
?>

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

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

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

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

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

つまり

if(!empty($_POST["name"]) && !empty($_POST["comment"])){
    // 更新モード
    if(!empty($_POST["number"])){
        // 更新処理を書く
    }
    // 新規追加モード 
    else{
        // 新規追加処理を書く
    }
}
// 削除モードの場合
elseif(!empty($_POST["delete"])){
    // 削除処理を書く
}


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

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


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

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

$date = date("Y/m/d H:i:s");
$delimiter = "<>";

if(!empty($_POST["name"]) && !empty($_POST["comment"])){
    $namae = $_POST["name"];
    $message = $_POST["comment"];

    if(!empty($_POST["number"]){
        $lines = file($filename);
        $number = $_POST["number"];

        $fp = fopen($filename, "w" );

        foreach($lines as $current_line){
            $posted_data = explode(" ",$current_line);

            if($posted_data[0] == $number){
                $update_line = implode( $delimiter, array( $number, $name, $message, $date) );
                fwrite( $fp, "$update_line\r\n");
            } else{
                fwrite( $fp, "$current_line\r\n");
            }
        }

        fclose($fp);
    } else{
        // 新規追加処理
    }
}

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/08/27 23:35

    ここまでしっかりと説明をいただけると思っていなかったので、うれしくて涙が出てきました…。

    写すのではなく、全て理解したうえで課題に取り組もうと思います。
    この度は本当にありがとうございます。

    キャンセル

+1

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 88.93%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る