上記を行う方法はありますか?基本的に、フォームを一度送信した後で誰かが更新を押した場合に、フォームが再度送信されることは望ましくありません。その場合、ブラウザは尋ねます、あなたはフォームをもう一度提出しますか?unset($_POST['username'])
この場合、何か助けになりますか?
11 に答える
一部の投稿者がすでに言及しているように、投稿/リダイレクト/取得は良いオプションです。
私が考えることができるもう1つの方法は、投稿がすでに行われたことを示すためにdostuff.phpページでセッションを設定することです。毎回このセッション変数をチェックして、ページの更新が原因でページが再度ロードされているかどうかを確認してください。
<?php
session_start();
if(isset($_SESSION['indicator']))
{
/*
dont do anything because session indicator says
that the processing was already done..
you might want to redirect to a new url here..
*/
}
else
{
/*
first set session indicator so that subsequent
process requests will be ignored
*/
$_SESSION['indicator'] = "processed";
//process the request here..
}
?>
リダイレクト先のページで、セッション変数の設定を解除して、フォームを新たに再送信できるようにし、新しいポスト操作にします。これにより、新しいフォームの投稿は許可されますが、ページの更新による投稿操作は防止されます
中間ページを使用して操作を実行してからリダイレクトします。
例えば:
mypage.php->フォームのあるページ
dostuff.php->フォームデータを受信して操作を行い、他のページにリダイレクトします。
リダイレクトを行うには:
次の行を「dostuff.php」の先頭に配置します。header("Location: mypage.php");
上記で直面している問題は、Post / Redirect / Getで解決できます(解決する必要があります) 。_POST
問題は別のリクエストであるため、php側で設定を解除しても効果がありません。
また、送信ボタンのダブルクリックにも対処する必要があります。これは、ボタンをクリックした後にフォームの送信を無効にするか、フォームにランダムトークンを入れてそのトークンをセッションに保存することにより、クライアント側で解決できます。トークンは1回だけ受け入れられます(セッションはトークンが投稿されたかどうかを追跡します)。
これは、ユーザーが同じデータを2回送信しないようにするために使用する優れた方法です。これにより、ページがリロード時に同じレコードをデータベースに追加することもできなくなります。
// First IF
if ($_SESSION['dup_comment_body'] == $_POST['comment_body']) {
echo 'You already entered that.';
} else {
// Second IF
if ($_POST['comment_body']) {
// Run your query here
$_SESSION['dup_comment_body'] = $_POST['comment_body'];
header('location:'.$_SERVER['REQUEST_URI'].'');
}
}
最初は、が最後に入力したものと等しいIF
かどうかを確認します( )。同じでない場合は、次に実行して、変数が空でないかどうかをテストします。最後の内側の下部に向かって、に等しくなるように設定します。したがって、次回の最初の実行で同じである場合、「あなたはすでにそれを入力しました。」というメッセージが表示されます。お役に立てれば!$_POST
$_SESSION
IF
$_POST
IF
$_SESSION['dup_comment_body']
$_POST
IF
$_POST
このコードを使用する
if(isset($_POST)){
header('location:'.$_SERVER['PHP_SELF']);
die();
}
これには、 POST / REDIRECT/GETパターンを使用する必要があります。
Post / Redirect / Get(PRG)は、一部の重複フォーム送信を防止するWeb開発デザインパターンであり、ユーザーエージェント(ユーザー)にとってより直感的なインターフェイスを作成します。PRGは、重複するフォーム送信を作成しない予測可能な方法でブックマークと更新ボタンをサポートします。
WebフォームがHTTPPOSTリクエストを介してサーバーに送信されると、特定のユーザーエージェントでサーバーの応答を更新しようとするWebユーザーが、元のPOSTリクエストの内容を再送信し、次のような望ましくない結果を引き起こす可能性があります。重複するWeb購入。
この問題を回避するために、多くのWeb開発者はPRGパターンを使用します。Webページを直接返す代わりに、POST操作はリダイレクトコマンドを返します。HTTP 1.1仕様では、HTTP 303(「その他を参照」)応答コードが導入され、この状況でWebユーザーのブラウザーが最初のPOST要求を再送信せずにサーバー応答を安全に更新できるようになりました。ただし、現在使用されている最も一般的な商用アプリケーション(新旧を問わず)は、これらの状況でもHTTP 302(「検出済み」)応答を発行し続けます。
PHPの例を次に示します。
header('Location: /yourpage.php', true, 303);
exit;
これに対する私の解決策は、post変数が設定されている場合にメタリフレッシュを実行することです。$ _ POSTは、リフレッシュ後にそれに従いません。
<head>
<?php
if (isset($_POST['Task'])){
echo' <meta http-equiv="refresh" content="0; url=./ThisFile.php">';
}
?>
</head>
フォームでデータベースを更新する場合は、レコードが存在しない場合にのみ更新または挿入できます。最初にselectステートメントを実行するだけです。これにより、更新によるレコードの重複を防ぐことができます。
このフォームの内容をデータベースに挿入する場合は、php / sql SELECTステートメントを使用して、「username」がすでに送信されているかどうかを確認してください。はいの場合、エラーをスローします。そのようです:
//Database Values: servername, dbname, username and password;
//Also set ($_POST['username']) = $username or anything you like;
$usererror = ""; //Will be filled later.
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt1 = $conn->prepare("SELECT * FROM yourdb WHERE username=:username");
$stmt1->bindParam(':email', $email);
$stmt1->execute();
$stmt1->fetch();
$querycheck = $stmt1->rowCount();
if ($querycheck >= 1) {
$usererror = "User already exists.";
}
}
catch(PDOException $e) {
// roll back the transaction if something failed
$conn->rollback();
echo "Critical Error. Contact admin immediately.";
error_log("Error: " . $e->getMessage(), 0); //logs connection errors instead of echoing the errors (for security reasons.)
}
$conn = null;
次に、フォームのみを挿入できます。エラーはありません。
If (empty($usererror)) {
//insert command
}
多くの記事で、php + sqlを使用してデータベースを操作するのが最も安全な方法であると言われているため、プリペアドステートメントを使用したことに注意してください。セキュリティ上の懸念があまりない場合は、通常の方法を使用することもできます。これにより、コード行も節約できます。
また、$ querycheck> = 1であることに注意してください。ユーザーが2,000回更新し、[戻る]ボタンをクリックして再度送信した場合でも、1回挿入し、1回を超えないようにすることが非常に重要です。$ querycheck>=1ではなく$querycheck>1を使用していたため、フォームは「AlreadyExists」エラーをスローする前に2回送信し続けました。最後に、私はそれを修正することができました。これが後でこの質問にアクセスする人々に役立つことを願っています。
フォームデータを処理した後、たとえば次のコードのように、$_POST配列をリセットできます。
<?php
if( isset($_POST['submit']))
{
//do some processing related to form;
//after done.....
$_POST = array(); //this declares post as empty array
//which is global variable anyways.
}
?>
または、2番目の方法は隠しフォームのものを使用することです...。
<?php
if( isset($_POST['submit']))
{
//do some processing related to form;
//create a form with hidden field
?>
<form method="post" name="myform" action="actionpage">
<input type="hidden" name="somename" value="">
</form>
<?php
echo "<script> document.forms['myform'].submit();</script>";
}
?>
これは基本的にnull値の1つのフィールドを持つフォームを送信します。これが最適かどうかはわかりませんが、ここでのニーズを満たします。
代わりに、キャプチャを実行せずに投稿を送信できないRecaptchaなどのキャプチャを使用できます。これは私が使用したものであり、完全に機能します。