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

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

ただいまの
回答率

88.62%

phpの掲示板 編集機能をつけたい

受付中

回答 1

投稿

  • 評価
  • クリップ 2
  • VIEW 524

canady

score 4

編集機能をつけたい

PHPで掲示板を作っています。
そこで編集機能をつけようとコードを付け加えたら複数のエラーが出てしまいました。
編集機能の部分が問題だと思い、色々コードを抜いたり付け加えたり書き換えたりもしたのですが、状況が変わらない為、どのように変えたらいいのか教えて欲しいです。

発生している問題・エラーメッセージ

Notice: Undefined index: editNo in /public_html/mission_3-4.php on line 67

Notice: Undefined variable: line in /public_html/mission_3-4.php on line 68

Warning: count(): Parameter must be an array or an object that implements Countable in /public_html/mission_3-4.php on line 68

Notice: Undefined variable: file in /public_html/mission_3-4.php on line 70

Notice: Undefined variable: line in /public_html/mission_3-4.php on line 72

Warning: Invalid argument supplied for foreach() in /public_html/mission_3-4.php on line 72

該当のソースコード

<html>
<head>
<meta charset="utf-8">
 <title>掲示板</title>
</head>
<body>

    <form action="mission_3-4.php" method="post">
    名前<br>
    <input type="text" name="name" ><br>
    コメント<br>
    <input type="text" name="comment"><br>
    <input type="submit"><br>

    <?php
    if(isset($_POST["name"])&& $_POST["name"] !=="");
    if(isset($_POST["comment"])&& $_POST["comment"] !=="")
    {
    $fileName = "mission_3-4.txt";
    $file = file($fileName, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);

    $num = sizeof($file) + 1;
    $userName = $_POST["name"];
    $comment = $_POST["comment"];
    $time = date("Y/m/d H:i:s");
    $write = $num. " ". $userName. " ". $comment. " ". $time. "\n";

    $fp = fopen($fileName, "a");
    flock ($fp, LOCK_EX);
    fwrite($fp, $write);
    flock ($fp, LOCK_UN);
    fclose($fp);

    $file = file($fileName, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    foreach ( $file as $value ) {  
        $line = explode("<>", $value);  
        echo $value."<br />\n";
    }
    } 
?>

    </form>
    <form method="post" action="mission_3-4.php">
    <label>削除対象番号<br> 
    <input name="delete_res" type="number"></label><br>
    <input type="submit" name="delete" value="送信">
</form>

    <?php
if (isset($_POST['delete'])) {
    $file = file('mission_3-4.txt');
    $num = $_POST['delete_res'];
    unset($file[$num]);
    file_put_contents('mission_3-4.txt', $file);
}
?>

 </form>
    <form method="post" action="mission_3-4.php">
    <label for ="edit">編集対象番号<br> 
    <input name="editNo" type="number"></label><br>
    <input type="submit" name="edit" value="送信">
</form>

  <?php
    if (isset($_POST['edit']));
     { $num = htmlspecialchars($_POST['editNo']); 
        for ($k = 0; $k < count($line) ; $k++) { 
    if (strpos($num.' ', $line[$k]) === 0) { $line[$k] =   $num.' '.$_POST['name'].'<>'.$_POST['comment'].'<>'.date('Y-m-d-H-i-s')."\n"; break; } } } 
  file_put_contents('mission_3-4.txt', $file);

foreach($line as $_POST){
    list($num, $userName, $comment, $time) = explode("<>", $_POST);
    echo h($num);
    echo h($userName);
    echo h($comment);
    echo h($time)."<br>\n";
}
function h($s)
{
    return htmlspecialchars($s, ENT_QUOTES, "UTF-8", true);
}
?>
</body>
</html>

試したこと

あのエラー文に対する他の方々の回答を基にコードを変えたりしたのですが、できませんでした。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • tanat

    2020/10/27 18:52

    teratail内で
    mission_3-4
    で検索すると良いですよ
    (書籍が残念な品質なので同じように困っている人が大勢います。)

    キャンセル

回答 1

+5

どのような質問や回答を参考にしたのか分かりませんが、
エラー自体はよくあるものとはいえ、コピペで解決するようなことはそうそうありませんので、そこだけ認識してください。

まずはエラーは「現在のコードにおける指摘事項」と思ったら良いです。
つまり、何が問題であるかときちんと教えてくれているわけです。
なので、まずはエラーを読みましょう。
エラーメッセージの読み方と対処, 検索や質問の原則

エラーを読んだら、あとはそのエラーへの理解です。
例えば今回ですと1つ目はこうなっていますね。

Notice: Undefined index: editNo
Notice:未定義のインデックス:editNo

「インデックス」という単語に馴染みがなくて混乱しているかもしれませんが、
再現できるコードは、例えば下記です。

$ar = [];
$ar["a"] = "hoge";
echo $ar["b"];

$arという変数を配列で定義してaというキーにhogeという文字列を代入しているにも関わらずbというキーで出力しようとしている。
つまり、存在していないキーを指定したときに出るNoticeであることが分かります。

これについてはteratail内でも結構投稿されています。
teratail: [Undefined index] の検索結果: 1240件 

ということで今回Noticeが出ている箇所を確認してみてください。
で、そのNoticeが出ている配列の変数が特定出来たら、直前で
var_dump(対象の変数);を入れてみましょう。

そうすることで、「その配列にどのような情報が格納されているか」が確認できます。
そこからは地道に「なぜこのキーが入っていないか」を見ていくしかありません。

他のエラーについても同様です。

このように「変数にどのようなデータが入っているか」「どの処理を通っているか」を確認する作業を「デバッグ」と言います。

場合により、PHPの標準関数にエラーが出ているときがあります(今回の1点出ていますね)
その場合は、PHP 関数名で検索してPHPマニュアルを確認します。

そこで関数の仕様を確認し、エラーと照らし合わせ、整合性を確認します。
PHPマニュアルを辞書代わりに使うということですね。それができるようになるだけで成長が著しくなると思います。

「読み方が分からないんだよ!」という場合は
関数の定義(プロトタイプ)を読むにはを確認して「どのように読むのか」を確認しておきましょう。

基本は「どういう情報を与えたら」「どういう結果が得られるか」という2点を見ておけば殆ど読めます。
公式のドキュメントであるため、確実な情報が書いてありますし、対応しているPHPのバージョンまで確認することで最新の仕様であることが分かると思います。

つまり、現状出ているような問題に対しては下記の3本柱をきっちり行うことができるようになれば、初心者であっても自己解決が可能となるということです。

  • エラー文をきちんと読むこと
  • デバッグを行うこと
  • PHPマニュアルを活用すること

特に今回はPHPでよく使われる機能であるforeach()の使い方を大きく間違えています(エラーも出てますね)。
PHPマニュアルを確認し、そこにあるサンプルコードも確認し、理解を深めましょう。


蛇足:
他にも気になった点があるので幾つか。

・ インデントはしっかり付けましょう。
下記A,Bはどちらが読みやすい?

//A
if($a){
echo "aaaa";}

//B
if($a){
    echo "aaaa";
}


どのような開発環境で行っているか分かりませんが、
もしメモ帳を含めた汎用的なテキストエディタであれば今すぐ変更を検討してください。
プログラミングに特化したエディタ、できればPHPに特化したものが望ましいですし、ある程度のスペックのあるPCをお使いであればIDE(Eclipseなど開発統合環境)を導入しましょう。
ソースコードのフォーマット機能もありますし、実行しなくとも構文エラーは拾ってくれます。
未定義の変数、定義されながら使われていない変数も警告してくれます。
以下はEclipseでフォーマット機能を使った例。
※個人の開発環境ゆえにエディタ側のみキャプチャし切り取っています。
イメージ説明

・処理の順番を理解しよう
コードは確かに上から流れていきますが、ブラウザで表示させる場合、
表示時点ではPHP側の処理は全て終わっています。
PHPはあくまでサーバーサイドで動作する言語であるため、ブラウザが解析しようとするのはあくまで出力されている部分のみとなります。
ですので、「出力がなくて処理だけで終わっている部分」をHTMLの中に含む必要はありませんし、関数の定義は余計に含んではいけません。
非常に読みづらいコードとなります。

関数定義だけでも別ファイルに切り出した方が良いのですが(共通化することで別のプログラムからも使えるから)どうしても1ファイルにまとめたいのでしたら下記のような順番で書くと良いです。
用語的には「ロジックとビュー(テンプレート)の区別」と言ったところでしょうか。

関数の定義
出力を伴わない処理
出力するデータを取得する処理

html
PHPで取得したデータ(場合によりここでループなどPHPの処理を入れる)
/html

・htmlspecialchars()は画面出力するときに利用する
データ保存時に使ってはいけません。入力チェックなどで弾くことはあっても、そこを通ったユーザーから入力されたデータはそのまま何も加工せずに保存すべきです。

・何度も使い、変更がない情報なら定数を利用する
mission_3-4.txtというファイル名。固定ですよね。
これはコピペですら何度も出すのはよろしくありません。
ファイル名が変更になった時に置き換えていくことになりますしね。
もし今後システムとして大きくなってきて1プログラムファイルだけで収まらない内容になってきたら「間違いなく置き換えていく作業」をしなければなりません。結構手間です。
今回変数使われてますが、定義する場所が定義する場所なので後半出てくる場所では使えない可能性もあります。
冒頭で定数として定義して全部に適用すると良いです。

・できれば$_POST直接参照ではなくfilter_input()を使おう
「フィルター」と名がついている通り、単体の入力チェックにも使えますし、もし参照しようとしているキーが定義されてなければnullが返って来ますので、今回のようなUndefined indexは発生しません。
返却値がnullかどうかを見れば良いのでコードも分かりやすくなります。

・コメントは最低限つけよう。
こういうのがあるだけでも何日か見なかった自分に向けたメッセージにもなります。

//htmlspecialchars()のラッパー関数。変数を画面出力する際に使う
function h($s)
{
    return htmlspecialchars($s, ENT_QUOTES, "UTF-8", true);
}

//削除処理
if (isset($_POST['delete'])) {


//編集処理
if (isset($_POST['edit']));
{

色々書いてはいますが、1つ1つ見ていけばおかしい点って結構出てくると思います。
何のために定義した変数か?何のために入れたifの分岐か?
==と=を間違っていないか?
変数名を大文字小文字間違っていないか?など。

自身で理解しているところをコメントつけていくと、自身の理解度も把握でき、全容も分かってきて問題の切り分けも出来るのではないかと思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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