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

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

ただいまの
回答率

90.50%

  • PHP

    22998questions

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

編集機能の実装について

受付中

回答 3

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 158

takakuni

score 6

前提・実現したいこと

ここに質問の内容を詳しく書いてください。
PHPで掲示板の編集機能システムを作っています。
編集番号を入力すると元の内容が投稿用のフォーム内に表示されるようになっています。
編集番号から値を受け取った場合にのみ、hiddenで編集番号が投稿フォームの下にあるような形です。
条件分岐として、hiddenに値があるときに、指定した番号と一致する投稿番号を上書き保存するような仕様にしたいです。

該当のソースコード

新規登録と上書き処理がごちゃごちゃな状態です。

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
        $value = $_POST['mode'];
        switch( $value ){
            case "insert":
            $name = $_POST['name'];
            $comment = $_POST['comment'];
            $time = date('Y年m月d日 H時i分s秒');
                if(!empty($edit)){
                  $ediCon = file($filename);
                  $fp = fopen($filename, "w");
                  for ($j = 0; $j < count($delCon); $j++) { // ループの初期化、変数delConの要素数より少ない分ループを行う。行った後はループを1足す。
                    $delData = explode("<>", $delCon[$j]);// コメントデータ$j行目を1つ取り出した情報を<>で分割した上で変数ediDataに格納
                    if ($ediData[0] == $edit) { //コメントデータの最初は「コメント番号」なのでそれと入力された対象番号を比較、同じ場合
                      $ediDatalist = $edidata[0]."<>".$name."<>".$comment."<>".$time."\n";
                      fwrite($fp, $ediDatalist); //書き込み
                    }
                }
              }
                if (file_exists($filename)) {
                  $fp2 = fopen('count_keiziban.txt','r');
                  $num_text = fgets($fp2);
                  fclose($fp2);
                  $number = (int)$num_text;
                  $number += 1;
                } else {
                  $number = 1;
                }
                $fp2 = fopen('count_keiziban.txt','w');
                fwrite($fp2, $number);
                fclose($fp2);

                // $datalist = $number."<>"."\t".$name."<>"."\t".$comment."<>"."\t".$time."\n";
                $datalist = $number."<>".$name."<>".$comment."<>".$time."\n";
                $fp = fopen($filename, 'a'); // 変数filenameを追記モードで開き、変数fpに代入
                fwrite($fp, $datalist); // 変数fpに変数datalistに書き込まれたデータを代入
                fclose($fp); // 変数をfpを閉じた。


投稿番号の受け取り

            case "edit":
                $edit = $_POST["edit"];
                $ediCon = file($filename);
                for ($j = 0; $j < count($ediCon); $j++) {
                  $ediData = explode("<>", $ediCon[$j]);
                  if ($ediData[0] == $edit){
                    $ediName = $ediData[1];
                    $ediComment = $ediData[2];
                  }
                }
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>keiziban</title>
  </head>
  <body>
    <form action="" method="post">
    名前: <input type="text" name="name" value="<?php echo $ediName ?>">
    コメント: <input type="text" name="comment" value="<?php echo $ediComment ?>">
    <input type="hidden" name="hidden" value="<?php echo $edit ?>">
    <button type="submit" name="mode" value="insert">登録する</button>

    削除対象番号:<input type="number" name="delete">
    <button type="submit" name="mode" value="delete">削除する</button>

    編集対象番号:<input type="number" name="edit">
    <button type="submit" name="mode" value="edit">編集する</button>
    </form>
<?php
      if (file_exists($filename)) {
       $datalists = file($filename);
       foreach ($datalists as $line) {
         $data = explode("<>", $line);
         echo '番号:'.h($data[0]).'<br />';
         echo h($data[2]).'<br />';
         echo 'By:'.h($data[1]).'<br />';
         echo '投稿日時'.h($data[3]).'<br />';
         echo '<hr />';
       }
     }else{
       echo "コメントが1件もありません";
     }
     ?>
     <p><?php echo "$ediName" ?></p> //試し書き
     <p><?php echo "$ediComment" ?></p> //試し書き
  </body>
</html>

試したこと

ファイル関数に、ついて調べましたが、一部を変更することがあまり出てこなくて、変更する場合にも文字列の長さが均等でないといけないと書いてあり、必要なことは、ファイルを一度からにしてそこからまた書き込むことということはわかったのですがイメージがつかず今に至ります。

調べて書き直した結果、全て追記保存になってしまう仕様になりました。

case "insert":
                $name = $_POST['name'];
                $comment = $_POST['comment'];
                $time = date('Y年m月d日 H時i分s秒');
                $hidden = $POST['hidden'];

                if (file_exists($filename)) {
                  $fp2 = fopen('count_keiziban.txt','r');
                  $num_text = fgets($fp2);
                  fclose($fp2);
                  $number = (int)$num_text;
                  $number += 1;
                } else {
                  $number = 1;
                }
                $fp2 = fopen('count_keiziban.txt','w');
                fwrite($fp2, $number);
                fclose($fp2);

                $datalist = $number."<>".$name."<>".$comment."<>".$time."\n";
                if ($hidden){
                  $datalists = file($filename);
                  $fp = fopen($filename, 'w');

                  foreach ($datalists as $datalist) {
                    $ediData = explode("<>", $datalists);
                    if ($ediData[0] == $hidden){
                      fwrite($fp, $hidden."<>".$name."<>".$comment."<>".$time);
                    } else {
                      $fp = fopen($filename, 'a'); // 変数filenameを追記モードで開き、変数fpに代入
                      fwrite($fp, $datalist); // 変数fpに変数datalistに書き込まれたデータを代入

                    }
                  }
                } else {
                  $fp = fopen($filename, 'a'); // 変数filenameを追記モードで開き、変数fpに代入
                  fwrite($fp, $datalist); // 変数fpに変数datalistに書き込まれたデータを代入
                }
                fclose($fp); // 変数をfpを閉じた。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • mts10806

    2019/03/14 13:17

    聞きたいことは何でしょうか

    キャンセル

  • takakuni

    2019/03/14 13:21

    聞きたことは、編集機能を実装するために、上書き保存するための編集後の内容を書き込む方法が知りたいです。

    キャンセル

  • mts10806

    2019/03/14 13:47

    答えるのはやぶさかではないですが、珍しい機能でもないですし、過去質問探した方がいいかもしれないですね。「簡易掲示板」と称してテキストファイルに内容を保存する課題についての質問が多く挙がってますし、質問者さんがやろうとしていることが既に実装済みのものもあるかもしれません。

    キャンセル

  • takakuni

    2019/03/15 10:48

    調べ直した結果このような形で行き詰ってしまいました。
    何か、助言をいただけると幸いです。

    キャンセル

回答 3

+1

個別の機能がよくわかっていない状態で機能を追加するのは中々無理があるので、
まずは「ファイルの一部を変更して保存しなおす」という機能だけを出来るだけシンプルに作って理解してみてはいかがでしょうか?

ファイル関数に、ついて調べましたが、一部を変更することがあまり出てこなくて、変更する場合にも文字列の長さが均等でないといけないと書いてあり、必要なことは、ファイルを一度からにしてそこからまた書き込むことということはわかったのですがイメージがつかず今に至ります。

流れとしては

  1. ファイルの内容を変数に読み込む
  2. 読み込んだ変数を使って更新後のファイルのデータ変数を作る(or 変数を書き換える)
  3. 変数をファイルに上書きする

使っている関数は違いますが例えばこんな感じです。
この内容が理解できないようであれば、もっと複雑な掲示板で実装することは難しいので、上記の1-3がどう実行されているか確認してみて下さい。

1<>"1行目"
2<>"2行目"
3<>"3行目"

というデータ(data.txt)があって、2行目のデータを書き換えるだけのPHP

$lines = file("data.txt",FILE_IGNORE_NEW_LINES);
foreach($lines as  $line){
    $fields = explode("<>",$line);
    //2行目の時だけ書き換える
      //ここでは2行目を決め打ちだが、実際はPOSTから取得したIDで判定する
    if($fields[0] === "2"){
      $fields[1] = "更新された2行目";
    }
    //出力用の配列に格納
    $newLines[] = implode("<>",$fields);
}

//ファイルへの書き込み fwriteを使ってもいいです
file_put_contents("data.txt",implode(PHP_EOL,$newLines));

実行後にdata.txtが以下に更新されます

1<>"1行目"
2<>更新された2行目
3<>"3行目"

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

+1

ちょっと動きが微妙かもしれませんが参考までに。。

1.編集番号を入力し、元の内容を投稿用フォーム内に表示。
2.再度編集ボタンを押下
3.ファイルを読み込み、編集番号と同じであればpostされたデータを上書き

case "edit":
    $edit = $_POST["edit"];
    $ediCon = file($filename);
    for ($j = 0; $j < count($ediCon); $j++) {
      $ediData = explode("<>", $ediCon[$j]);
      if ($ediData[0] == $edit){
        $ediName = $ediData[1];
        $ediComment = $ediData[2];
      }
    }

    // 編集番号取得
    $hidden = filter_input(INPUT_POST, 'hidden');

    // 編集番号(hidden)があれば・・
    if ( $hidden ) {
        $name    = filter_input(INPUT_POST, 'name');
        $comment = filter_input(INPUT_POST, 'comment');
        $time    = date("Y/m/d H時i分s秒");

        $contents = file($filename);
        $fp       = fopen($filename, 'w');

        foreach($contents as $content) {
            $parts = explode("<>", $content);

            // 編集番号と同じだったらpostされたデータに上書き
            if ( $parts[0] == $edit ) {
                fwrite($fp, $name."<>".$comment."<>".$time."\n");
            } else {
            // 違う場合はそのまま書き込み
                fwrite($fp, $content);
            }
        }
        fclose($fp);

        // 元のページに戻る??
        header('Location:'.$_SERVER['REQUEST_URI']);
        exit;
    }

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

+1

直接解決になるか分かりませんが、「試したこと」のコード、1箇所おかしいですね。
$POST['hidden']
ではなく
$_POST['hidden']です。
この間違い、結構良くあります。
学習段階では特にこの間違いは勿体無いのでPHPマニュアルからコピペして使うようにすると良いです。

そもそもが変数未定義のなどのエラーになっていそうに思います。
学習段階・開発途中段階では必ずエラー表示Onにしてください。

ただ、スーパーグローバル変数を直接使うより今はfilter_input()を使ったほうが良いです(参考記事
シンプルに書けますし検証フィルタを使えば入力チェックにもなります。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

  • PHP

    22998questions

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