バージョン
mysql Ver 15.1 Distrib 10.4.11-MariaDB
PHP 7.4.1
【掲示板の完成後】
掲示板を作成できたと思ってリロード(更新ボタン)を押したら二重投稿や空白のまま投稿がされてしまうというような事態に陥らないように今回はリロード防止と空白時は投稿できないというソースコードを書いてみました。
PHP構文は非常に短いコードで作成したので是非一読してみてくださいね(^O^)
Menu
ディレクトリ
aaa.php
掲示板のPHPコードとHTMLを記述しています。
bbb.php
リダイレクトさせるためだけのページです。
css\style.css
掲示板の書式などをこちらに記述しています。
データベース
(mysql Ver 15.1 Distrib 10.4.11-MariaDB)
使用するカラムは3つ
id 連番
content 記事内容
create_at 投稿時間
PHPとHTML
aaa.php
(最初のREQUEST_METHODでリダイレクトさせてGETとPOSTの処理を上手く利用してリロードで二重投稿防止と空白時の処理を行っています。)
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | <?php //リロード重複処理 REQUEST_METHODを使用して回避 if ($_SERVER['REQUEST_METHOD'] === 'POST') { header('Location:http://localhost/study/bbb.php'); } $dsn = 'mysql:dbname=study;host=localhost'; $user = 'root'; $pass = ''; try { $pdo = new PDO($dsn, $user, $pass); if (empty($_POST['content'])) { // データベースから投稿内容を取得 $stmt = $pdo->query('SELECT * FROM boards'); $pdo = null; } else { $content = $_POST['content']; // 投稿内容をデータベースに挿入 $stmt = $pdo->prepare('INSERT INTO boards(content)VALUES(?)'); $stmt->execute([$content]); $pdo = null; } } catch (PDOException $e) { print($e->getMessage()); die(); } ?> <!--///////////ここまでphp/////////--> <!--///////////ここからHTML//////////////////--> <!DOCTYPE html> <html lang="jn"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="css/style.css"> <title>簡易掲示板</title> </head> <body> <?php //表示 $h = 'htmlspecialchars'; foreach ($stmt as $key => $val) { echo '<div class="bord_area">'; echo '<div class="id"><label for="id">' . ($val["id"]) . '</label></div>'; echo '<div class="create_at"><label for="id">' . $h($val["create_at"], ENT_QUOTES) . '</label></div>'; echo '<div class="content"><label for="id">' . ($val["content"]) . '</label></div>'; echo '</div>'; } ?> <div class="form_area"> <form action="aaa.php" method="POST"> <div class="post_content"> <label for="">レス本文</label> <textarea class="form-control" name="content" id="content" rows="5"></textarea> </div> <div class="bt_area"> <button type="reset" name="reset" class="btn btn-primary">リセット</button> <button type="submit" name="submit" class="btn btn-primary">送信</button> </div> </form> </div> <script> // 入力後、一番下にスクロールをする var element = document.documentElement; var bottom = element.scrollHeight - element.clientHeight; window.scroll(0, bottom); </script> </body> </html> |
bbb.php
(リダイレクトでPOSTをGETにするだけのphp)
1 2 3 | <?php header('Location:http://localhost/study/aaa.php'); ?> |
CSS
style.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | @charset "UTF-8"; /* @import url("style2.css"); */ .form_area{ width: 200px; } .bord_area{ margin-bottom: 30px; border-bottom: solid 1px; } .post_content{ margin-bottom: 5px; } .bt_area{ margin-right: 30px; text-align: right; } .id{ display: inline; padding-right: 7px; } .create_at{ display: inline; } |
リロード防止と空白の回避をする処理内容
下記3点をREQUEST_METHODでPOSTかGETどちらで受け取ったかを確認後に処理を実施します。
なぜheader処理(リダイレクト)させるかというとリダイレクトしたタイミングでPOSTがGETに変換するのでそれを上手に利用するということになります。
POSTの投稿内容がある場合はINSERT処理後にリダイレクトさせることにより、POSTが空になるのでリダイレクトで戻ってきた際のif判定でDBからデータの取得と表示ができるようになります。
この辺の解説は言葉で説明するよりご自身でデバッグして実際の動きを確認したほうがより理解ができます。
VSCodeがある方はVSCodeでデバッグする方法で確認できます。
簡単に説明しますと下記の3つのパターンでボタンが押された際、次のような流れで動作します。
①リロード(ブラウザ更新ボタン)が押された場合 初期GET
最初に受け取った値がGETなのでリダイレクト処理はなしです。
②投稿内容がない場合(送信ボタン) 初期POST
最初に受け取った値がPOSTなのでリダイレクト処理が入ります。
③投稿内容がある場合(送信ボタン) 初期POST
最初に受け取った値がPOSTなのでリダイレクト処理が入ります。
(リダイレクトする前にINSERTでDBに投稿内容を挿入します)
まとめ
今回のPHP掲示板の作成にあたり変数の中身やREQUEST_METHOD判定後のリダイレクトのタイミング、そしてPOSTとGETの切り替わりがどのタイミングで変わるかをデバッグ機能で確認する事ができれば今回のリロードによる二重投稿防止と空白投稿防止の処理は難しい処理ではなくなります。
是非この機会にご自身でデバッグする力を身に着けてPHPの動きをご自身の目で確認できるような技術を身に着けてみてはいかがでしょうか!
ご興味がある人は是非一度VSCodeでデバッグする方法で確認してみてください!
データベースMySqlもしくはMariaDBを作成できれば、あとは全てコピペで同じものが作成できますので、簡易掲示板作成にてこずっている方は是非コピペして試してみてください。
あとはログインページ機能を作成すれば会員専用の掲示板サイトも作成が可能になります。
以上、簡易掲示板でした(^O^)