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

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

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

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

Q&A

2回答

5018閲覧

PHP掲示板 編集機能実装について

germanium

総合スコア11

PHP

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

0グッド

0クリップ

投稿2017/10/27 17:44

PHPで簡易掲示板を作っております。
下記コードで編集機能を実装しようとしています。
「各投稿番号とPOST送信されてきた編集番号を比較し、等しい場合、配列値を取得する」
ことはできたと思うのですが、
「入力フォームに取得した配列値を上書きで表示する」
ことができません。どのように書き直したらいいか、回答お願いいたします。

例えば、投稿番号が1、名前がabcd、コメントがnovelという投稿だけがもともとあるとします。その状態で編集対象番号に1を入力し、送信すると、フォームの名前のところにabcd、コメントのところにnovelが出力され、これを名前をefgh、コメントをsongに編集し、送信すると投稿番号2(名前:efgh、コメント:song)が新たに追加されます。
これを投稿番号1で名前:efgh、コメント:songだけが存在する状態にしたいのですが…

よろしくお願いいたします。

PHP

1<?php 2 3 $name = $_POST['name']; 4 $name = htmlspecialchars($name); 5 6 $comment = $_POST['comment']; 7 $comment = htmlspecialchars($comment); 8 9 $delete = $_POST['delete']; 10 $delete = htmlspecialchars($delete); 11 12 $edit = $_POST['edit']; 13 $edit = htmlspecialchars($edit); 14 15 $time = date("Y/m/d H:i:s"); 16 17 $line = file("mission_2-2.txt"); 18 $num = count($line); 19 20 $write = "{". $num . "}<>{" . $name . "}<>{" . $comment . "}<>{" . $time . "}"; 21 22 if (!empty($name) && !empty($comment)) { 23 $fp = fopen ("./mission_2-2.txt","a"); 24 fputs ($fp, $write."\n"); 25 fclose ($fp); 26 } 27 28 if (!empty($delete)) { 29 $delCon = file("mission_2-2.php"); 30 for ($j = 0; $j < count($delCon) ; $j++) { 31 $delData = explode("<>", $delCon[$j]); 32 if ($delData[0] == "{".$delete."}") { 33 array_splice($delCon, $j, 1); 34 file_put_contents("./mission_2-2.txt", $delCon); 35 } 36 } 37 } 38 39 // $editが'0'のときif文通らない 40 if (!empty($edit)) { 41 $ediCon = file("mission_2-2.txt"); 42 for ($k = 0; $k < count($ediCon) ; $k++) { 43 $ediData = explode("<>", $ediCon[$k]); 44 if ($ediData[0] == "{".$edit."}") { 45 //$simEdit = explode("}<>{", $ediCon[$k]); 46 for($h = 0; $h < count($ediData); $h++){ 47 $simEdit[$h] = mb_substr(trim($ediData[$h]), 1, -1); 48 } 49 } 50 } 51 } 52 53 54?> 55<!DOCTYPE html> 56<html> 57 58<head> 59<meta charset="UTF-8"> 60<title>favorite book</title> 61</head> 62 63<body> 64 <form method="POST" action="<?php echo($_SERVER['PHP_SELF']) ?>"> 65 <label for="name">名前:</label> 66 <input type="text" name="name" value="<?php echo $simEdit[1]; ?>"><br><br> 67 68 <label for="comment">コメント:</label> 69 <textarea name="comment" cols="30" rows="5"><?php echo $simEdit[2]; ?></textarea><br> 70 <input type="submit" value="投稿する"> 71 </form> 72 73 <br> 74 75 <form method="POST" action="<?php echo($_SERVER['PHP_SELF']) ?>"> 76 <label for="delete">削除対象番号</label><br> 77 <input type="text" name="delete"><br> 78 <input type="submit" value="削除する"> 79 </form> 80 81 <br> 82 83 <form method="POST" action="<?php echo($_SERVER['PHP_SELF']) ?>"> 84 <label for="edit">編集対象番号</label><br> 85 <input type="text" name="edit"><br> 86 <input type="submit" value="編集する"> 87 </form> 88 89<?php 90 91 $contents = file('mission_2-2.txt'); 92 foreach($contents as $line){ 93 $data = explode("<>", $line); 94 for($i = 0 ; $i < count($data); $i++){ 95 echo $data[$i]."<br>"; 96 97 } 98 } 99 100?> 101</body> 102</html>

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

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

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

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

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

guest

回答2

0

挙動がおかしい時は一般的に条件分岐が意図していない動作をしている場合が多いです。
条件文内の変数を追うことで、意図通り動くように修正することができるようになります。
変数を追うには、デバッグ環境を整え、ステップ実行し、変数の変移を追うと良いです。

また、本件では常に「NOTICE」レベルのエラーが出る記述になっています。
表示されていないのであれば、それは「E_NOTICE」の表示が on になっていないからです。
デバッグ中は「エラー表示」のすべてを常に on することで問題点を確認することが重要です。

ざっくりとですが、問題点は以下のとおりです。
・form 文の構成がおかしい
・if 文の設計がおかしい
・$_POST が空の時の対応が記述されていない
・htmlspecialchars の使用箇所が悪い

ブラウザの「開発ツール」を使用することで POST 内容を確認できますので、そちらも併せて使用すると、デバッグがはかどります。

投稿2017/10/27 22:15

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

germanium

2017/10/28 06:15

ご回答いただきありがとうございます 常にnoticeエラーが出るとのことですが、私のパソコン上ではエラーが出ずに 普通に表示されます。これはどのような原因によるものでしょうか
退会済みユーザー

退会済みユーザー

2017/10/28 06:47

「E_NOTICE」の表示が on になっていないからです。
guest

0

htmlspecialchars関数はあくまでHTMLに出力するための関数です。

php

1 2$name = $_POST['name']; 3$name = htmlspecialchars($name); 4 5$comment = $_POST['comment']; 6$comment = htmlspecialchars($comment); 7 8$delete = $_POST['delete']; 9$delete = htmlspecialchars($delete); 10 11$edit = $_POST['edit']; 12$edit = htmlspecialchars($edit);

こんなコードはクロスサイトスクリプティング(XSS)の脆弱性となります。

ユーザー入力を受け取るには $_POST変数がセットされているかかつ文字列であるかというのをチェックしてそうでなかったら nullを代入する必要があります。

php

1function postCheck($name) 2{ 3 if (isset($_POST[$name]) && is_string($_POST[$name])) { 4 return $_POST[$name] 5 } 6 return null; 7} 8 9$name = postCheck('name'); 10$comment = postCheck('comment'); 11$delete = postCheck('delete'); 12$edit = postCheck('edit');

とするか 以下のようにfilter_input関数を用いる必要があります。

php

1$name = (string)filter_input(INPUT_POST,'name'); 2$comment = (string)filter_input(INPUT_POST,'comment'); 3$delete = (string)filter_input(INPUT_POST,'delete'); 4$edit = (string)filter_input(INPUT_POST,'edit');

htmlspecialchars関数の正しい使い方は以下のようにHTMLに出力する場合に使うべきです。

php

1<p><?php echo htmlspecialchars($name, ENT_QUOTES,"UTF-8"); ?></p>

投稿2017/10/28 06:47

naohiro19_

総合スコア178

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

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

退会済みユーザー

退会済みユーザー

2017/10/28 06:51

一番上のサンプルスクリプトでクロスサイトスクリプティング(XSS)が発生すると記述がありますが、どのようなケースでしょうか?
germanium

2017/10/28 07:06

ありがとうございます。 htmlspecialchars関数の使い方に関して思い違いをしていたようです。 改善します
naohiro19_

2017/10/28 16:44

htmlspecialchars関数は <script>alert('hello world!');</script> のような文字列を &lt;script&gt;alert(&#039;hello world!&#039;);&lt;/script&gt; に変換してくれる関数なのでデータベースのパラメータに入れるのは間違っていますからね。
退会済みユーザー

退会済みユーザー

2017/10/28 20:19 編集

もう少しちゃんと書いてほしかったので、質問したのですけど、スルーされちゃいましたね^^; htmlspecialchars の使用に際して、デフォルトのまま使用することは推奨されません。第2,第3引数まで指定することが一般的です。 これは、デフォルトのままだとシングルクォーテーション(')をエスケープしないからです。今回は、HTML の記述においてシングルクォーテーションを使用していないので脆弱性にはなりませんが、予防処置として htmlspecialchars($str, ENT_QUOTES, 'UTF-8') のように、第2引数に ENT_QUOTES を指定し、第3引数で変換に使用 される文字セットを記述することが推奨されています。 また、出力時以外の箇所でエスケープすることが正しくないのは、以下のリンク先の mpyw さんの回答が参考になります。 https://ja.stackoverflow.com/questions/2408/%E8%84%86%E5%BC%B1%E6%80%A7%E5%AF%BE%E7%AD%96%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8Bhtmlspecialchars%E3%81%AE%E4%BD%BF%E7%94%A8%E7%AE%87%E6%89%80%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6 こちらも今回のスクリプトでの影響はありませんが、習慣として、出力時にエスケープすべきです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問