前回、1ページでの掲示板を作成しました。
しかし、ページをリロードする際にPOSTデータが再送されてしまう「2重送信」の状態になっています。
今回はこれを回避するために、コメント送信後に別のページに遷移する仕組みを作って、掲示板を完成させたいと思います。
PHPファイルを2つ作成する事で、可能になります。
事前に、ドキュメントルートに掲示板のホーム画面となるPHPファイルと、コメント送信後に遷移するページのPHPファイルの2つを作成しておきます。
前者をindex.php、後者をkanryo.php、とします。
なお、今回使用するphpのプログラムは冒頭の過去記事で詳細をまとめていますので、この記事でのphp文の挙動については、詳細な説明を省きます。
CSSでスタイリングすれば、完成した掲示板はこんな感じになります。↓
なお、無料サーバーにて完成した掲示板を公開しております。↓
目次
初めに
作成する掲示板のプログラムの流れ
今回作成する掲示板のおおまかなプログラムの流れを記しておきます。
①index.phpからコメントをPOST送信
②kanryou.phpに遷移、POSTデータを受け取る(この時点でindex.phpのPOSTは空になる)
③kanryou.phpでデータベースに接続、テーブル参照、POSTデータをテーブルに書き込む
④kanryou.phpに「書き込み完了」のメッセージを表示させ、掲示板へ戻るindex.phpのリンクを貼る
⑤index.phpでデータベースに書き込まれた一覧を表示させる。リロードしてもPOSTは空なので、二重送信にはならない
index.php
投稿フォームとデータベースに書き込まれた内容を表示させる
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>掲示板</title> <link rel="stylesheet" href="scc/style.css"> </head> <body> <form action="kanryou.php" method="post"> <p>名前</p> <input type="text" name="a"> <p>コメント</p> <textarea name="b"></textarea> <input type="submit" value="送信"> <br><br> </form> <?php $db = new PDO("mysql:host=localhost;dbname=keiji", "root", ""); $n = $db -> query("SELECT * FROM tb1 ORDER BY no DESC"); while($i = $n -> fetch()) { print "{$i['no']}: {$i['name']} {$i['time']}<br>" .nl2br($i['messege'])."<hr>"; } ?> </body> </html> |
formタグに「action=”kanryou.php”」を加えました。これは、POST送信時に指定のページへ移動する記述になります。
phpの記述は、「データベースに接続」「テーブルの内容を書きだし」を行っています。
つまり、このページにアクセスした段階で、すでにデータベースに保存されている内容が表示されます。
$_POST関数はkanryou.phpで記述しているため、変数未定義エラーは起こりおません。
また、POST送信後ページ移動を行うので、戻ってきた時にはPOSTが空の状態になるので、リロードしても2重投稿にはなり得ません。
なお、データベース接続のphp文は、データベースを利用する全てのページで記述する必要があります。したがって後述するkanryou.phpにも記述していますが、こちらのindex.phpでも記述が必要になります。
kanryou.php
変数未定義の回避、POSTの受け取り、DBへ書き込みを行う
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>掲示板</title> <link rel="stylesheet" href="scc/style.css"> </head> <body> <?php if(!empty($_POST["a"]) && !empty($_POST["b"])) { $a = htmlspecialchars($_POST["a"], ENT_QUOTES); $b = htmlspecialchars($_POST["b"], ENT_QUOTES); $db = new PDO("mysql:host=localhost;dbname=keiji", "root", ""); $db -> query("INSERT INTO tb1(no, name, messege, time) VALUES(NULL, '$a', '$b', NOW())"); print "<h1>コメント送信完了しました</h1>"; print "<p><a href=index.php>掲示板へ戻る</a></p>"; } else { print "<h1>※フォームが入力されていません</h1>"; print "<p><a href=index.php>掲示板へ戻る</a></p>"; } ?> </body> </html> |
phpの先頭にあるif文!emptyで、$_POSTの空送信を防いでいます。空送信すると、なにも処理せずに「フォームが入力されていません」の表示を出すようにしています。
変数未定義もこのif文で回避できます。
フォームに内容が入力された場合のみ、データベース処理の部分へ進みます。
データベース接続後、テーブルを読み込み、POSTされた内容を書き込みます。
その後に、書き込みOKとの表示と、掲示板へ戻るURLをprintしています。
一つだけネックなのは、このページをリロードした場合、POSTした内容が二重送信されてしまう点です。(送信が成功している場合)
ユーザーからすれば送信が成功しているのでリロードする事はないでしょうが、プログラム上どうしてもそうなってしまいます。(コレを回避するにはセッションとかcookieなどを扱える知識が必要)
ただし、index.phpをリロードしても問題は起こらないので、前回のように1ファイルで作成するよりは断然今回の構成の方が良いと思われます。
最後に、今回の掲示板のファイル一式をGitHubに公開していますので、良ければDLしてください。↓