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

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

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

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

Q&A

1回答

2514閲覧

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

canady

総合スコア4

PHP

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

0グッド

2クリップ

投稿2019/12/07 16:49

編集機能をつけたい

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

該当のソースコード

php

1<html> 2<head> 3<meta charset="utf-8"> 4 <title>掲示板</title> 5</head> 6<body> 7 8 <form action="mission_3-4.php" method="post"> 9 名前<br> 10 <input type="text" name="name" ><br> 11 コメント<br> 12 <input type="text" name="comment"><br> 13 <input type="submit"><br> 14 15 <?php 16 if(isset($_POST["name"])&& $_POST["name"] !==""); 17 if(isset($_POST["comment"])&& $_POST["comment"] !=="") 18 { 19 $fileName = "mission_3-4.txt"; 20 $file = file($fileName, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); 21 22 $num = sizeof($file) + 1; 23 $userName = $_POST["name"]; 24 $comment = $_POST["comment"]; 25 $time = date("Y/m/d H:i:s"); 26 $write = $num. " ". $userName. " ". $comment. " ". $time. "\n"; 27 28 $fp = fopen($fileName, "a"); 29 flock ($fp, LOCK_EX); 30 fwrite($fp, $write); 31 flock ($fp, LOCK_UN); 32 fclose($fp); 33 34 $file = file($fileName, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); 35 foreach ( $file as $value ) { 36 $line = explode("<>", $value); 37 echo $value."<br />\n"; 38 } 39 } 40?> 41 42 </form> 43 <form method="post" action="mission_3-4.php"> 44 <label>削除対象番号<br> 45 <input name="delete_res" type="number"></label><br> 46 <input type="submit" name="delete" value="送信"> 47</form> 48 49 <?php 50if (isset($_POST['delete'])) { 51 $file = file('mission_3-4.txt'); 52 $num = $_POST['delete_res']; 53 unset($file[$num]); 54 file_put_contents('mission_3-4.txt', $file); 55} 56?> 57 58 </form> 59 <form method="post" action="mission_3-4.php"> 60 <label for ="edit">編集対象番号<br> 61 <input name="editNo" type="number"></label><br> 62 <input type="submit" name="edit" value="送信"> 63</form> 64 65 <?php 66 if (isset($_POST['edit'])); 67 { $num = htmlspecialchars($_POST['editNo']); 68 for ($k = 0; $k < count($line) ; $k++) { 69 if (strpos($num.' ', $line[$k]) === 0) { $line[$k] = $num.' '.$_POST['name'].'<>'.$_POST['comment'].'<>'.date('Y-m-d-H-i-s')."\n"; break; } } } 70 file_put_contents('mission_3-4.txt', $file); 71 72foreach($line as $_POST){ 73 list($num, $userName, $comment, $time) = explode("<>", $_POST); 74 echo h($num); 75 echo h($userName); 76 echo h($comment); 77 echo h($time)."<br>\n"; 78} 79function h($s) 80{ 81 return htmlspecialchars($s, ENT_QUOTES, "UTF-8", true); 82} 83?> 84</body> 85</html>

試したこと

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

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

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

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

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

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

tanat

2020/10/27 09:52

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

回答1

0

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

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

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

Notice: Undefined index: editNo

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

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

php

1$ar = []; 2$ar["a"] = "hoge"; 3echo $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はどちらが読みやすい?

php

1//A 2if($a){ 3echo "aaaa";} 4 5//B 6if($a){ 7 echo "aaaa"; 8}

どのような開発環境で行っているか分かりませんが、
もしメモ帳を含めた汎用的なテキストエディタであれば今すぐ変更を検討してください。
プログラミングに特化したエディタ、できれば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かどうかを見れば良いのでコードも分かりやすくなります。

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

php

1//htmlspecialchars()のラッパー関数。変数を画面出力する際に使う 2function h($s) 3{ 4 return htmlspecialchars($s, ENT_QUOTES, "UTF-8", true); 5} 6 7//削除処理 8if (isset($_POST['delete'])) { 9 10 11//編集処理 12if (isset($_POST['edit'])); 13{ 14

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

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

投稿2019/12/07 20:52

m.ts10806

総合スコア80842

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問