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

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

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

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

Q&A

解決済

3回答

2061閲覧

php:一言掲示板でリロードによる二重送信をさせないようにしたいです。

haru_7528

総合スコア1

PHP

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

0グッド

0クリップ

投稿2021/04/20 15:19

前提・実現したいこと

一言掲示板を作成しています。
リロードによる二重送信をさせないようにしたいです。

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

リロードすると二重投稿されてしまいます。

該当のソースコード

php

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8</head> 9<body> 10 <form action="index.php" method="post"> 11 <label for="comment">投稿者</label> 12 <input type="text" name="name"> 13 <br> 14 <label for="comment">内容</label> 15 <input type="text" id="comment" name="content"> 16 <input type="submit"> 17 </form> 18 19<?php 20 21//DBへの接続 22$dsn = 'mysql:dbname=board; host=localhost'; 23$username= 'root'; 24$password= 'root'; 25 26try{ 27 $dbh = new PDO($dsn, $username, $password); 28 $sql = "INSERT INTO boards (name, content) VALUES(:name, :content)"; 29 $stmt = $dbh->prepare($sql); 30 $params = array(':name' => $_REQUEST['name'], ':content' => $_REQUEST['content']); 31 $stmt->execute($params); 32} catch(PDOException $e){ 33 echo "失敗:" . $e->getMessage() . "\n"; 34 exit(); 35} 36 37$sql = "SELECT * FROM boards ORDER BY id DESC"; 38$stmt = $dbh->query($sql); 39 40 echo "<table>"; 41 echo "<tr>"; 42 echo "<th>Id</th><th>お名前</th><th>メッセージ</th>\n"; 43 echo "</tr>"; 44 foreach ($stmt as $user) { 45 echo "<tr>"; 46 echo "<td>" . $user['id'] . "</td>"; 47 echo "<td>" . $user['name'] . "</td>"; 48 echo "<td>" . $user['content'] . "</td>"; 49 echo "<td>" . "<a href=edit.php?id=" . $user['id'] . ">編集</a>" . "</td>"; 50 echo "<td>" . "<a href=delete.php?id=" . $user['id'] . ">削除</a>" . "</td>"; 51 echo "</tr>"; 52 } 53 echo "</table>"; 54 55?> 56</body> 57</html>

試したこと

以下のコードをINSERT文の後の方に記述しても防止はできませんでした。
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
header('Location: http://localhost:8888/board/');
}

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答3

0

いっそのことformタグとsubmitではなくbuttonでJavascriptからの非同期通信で投稿しては如何でしょう。

投稿2021/04/21 00:20

m.ts10806

総合スコア80875

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

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

0

postしてデータが確定したあとに確定ページにheader("Location")で飛ばしてください

投稿2021/04/21 00:18

yambejp

総合スコア116734

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

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

0

ベストアンサー

以下のコードをINSERT文の後の方に記述しても防止はできませんでした。
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
header('Location: http://localhost:8888/board/');
}

header() は HTMLなど出力した後には有効にならないため、
<!DOCTYPE html>より前にする必要があります。

PHPマニュアル
https://www.php.net/manual/ja/function.header.php

覚えておいて頂きたいのは、header() 関数は、 通常の HTML タグまたは PHP からの出力にかかわらず、すべての実際の 出力の前にコールする必要があることです。

以下を試してみてください。

  • 試した if文をソースコードの先頭に記述
  • INSERT処理は 上記 if文の中に記述

これで、POSTの時だけ INSERT文とheader()実行され、
リロード時もリダイレクトしているので期待通りになる気がします。
(未検証なので何か間違っているかもしれません)

投稿2021/04/20 15:50

satokei

総合スコア1217

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

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

haru_7528

2021/04/21 00:25

ありがとうございます!できました! 以下のように修正したところ想定通りの動作になりました。 追加でお聞きしたいのですが、 DB接続の部分が二重に記述しないといけないのですが、1回ですませるにはどのように修正すればよろしいでしょうか? ■コード <?php if ($_SERVER['REQUEST_METHOD'] === 'POST') { header('Location: http://localhost:8888/board/'); $dsn = 'mysql:dbname=board; host=localhost'; $username= 'root'; $password= 'root'; try{ $dbh = new PDO($dsn, $username, $password); $sql = "INSERT INTO boards (name, content) VALUES(:name, :content)"; $stmt = $dbh->prepare($sql); $params = array(':name' => $_REQUEST['name'], ':content' => $_REQUEST['content']); $stmt->execute($params); } catch(PDOException $e){ echo "失敗:" . $e->getMessage() . "\n"; exit(); } } ?> <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <form action="index.php" method="post"> <label for="comment">投稿者</label> <input type="text" name="name"> <br> <label for="comment">内容</label> <input type="text" id="comment" name="content"> <input type="submit"> </form> <?php //DBへの接続 $dsn = 'mysql:dbname=board; host=localhost'; $username= 'root'; $password= 'root'; try{ $dbh = new PDO($dsn, $username, $password); // $sql = "INSERT INTO boards (name, content) VALUES(:name, :content)"; // $stmt = $dbh->prepare($sql); // $params = array(':name' => $_REQUEST['name'], ':content' => $_REQUEST['content']); // $stmt->execute($params); } catch(PDOException $e){ echo "失敗:" . $e->getMessage() . "\n"; exit(); } $sql = "SELECT * FROM boards ORDER BY id DESC"; $stmt = $dbh->query($sql); echo "<table>"; echo "<tr>"; echo "<th>Id</th><th>お名前</th><th>メッセージ</th>\n"; echo "</tr>"; foreach ($stmt as $user) { echo "<tr>"; echo "<td>" . $user['id'] . "</td>"; echo "<td>" . $user['name'] . "</td>"; echo "<td>" . $user['content'] . "</td>"; echo "<td>" . "<a href=edit.php?id=" . $user['id'] . ">編集</a>" . "</td>"; echo "<td>" . "<a href=delete.php?id=" . $user['id'] . ">削除</a>" . "</td>"; echo "</tr>"; } echo "</table>"; ?> </body> </html>
satokei

2021/04/21 01:38

> DB接続の部分が二重に記述しないといけないのですが、1回ですませるにはどのように修正すればよろしいでしょうか? if文の外に出して、ソースコードの先頭で接続すればよいかと思います。 (select文では、これを流用する)
haru_7528

2021/04/22 12:26

ありがとうございます! できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問