2017-08-24 12 views
0

PHP関数を呼び出して電子メールを送信する単純なHTMLフォームボタンが2つあります。 1つのこと以外はすべて正常に動作します。いずれかのボタンをクリックしてレポートを送信した後、ページが更新されると、関数が再度呼び出されたように見え、ブラウザの更新ボタンを使用してユーザーがページを更新しても電子メールが再表示されます。PHP関数を呼び出すときにページが更新されると関数が繰り返される

ページが最新表示されている場合は、クリックされた最後のボタンからメールが再度送信されます。ボタン1をクリックしてページを更新すると、ボタン1の2つのレポートが表示されます。ボタン1をクリックしてボタン2をクリックすると、2番目のレポートだけが表示されます。ボタン#2を押してから#1をクリックすると、レポート#1だけが再び出ます。

このように、何個のボタンがクリックされても、ページを更新すると最後のボタンクリック(繰り返しのみ)が発生します。リクエストパラメータ(以下のコード)の設定を解除しようとしても、ページをリフレッシュすることによるリピートには影響しません。

ページリフレッシュ時に、最後にクリックされたボタンがセットとして表示されている理由と、unsetコマンドが機能しない理由がわかりません。

ありがとうございました。

if(isset($_REQUEST['email_this_weeks_report'])) { 
    unset($_REQUEST['email_last_weeks_report']); 
    #send email now email code for this week 

}  
if(isset($_REQUEST['email_last_weeks_report'])) { 
    unset($_REQUEST['email_last_weeks_report']); 
    #send email now email code for last week 

} 

<form>   
    <input class="ui-button ui-widget ui-corner-all" type="submit" 
name="email_this_weeks_report" value="Email This Weeks Report Now" /> 
</form> 

<form>   
    <input class="ui-button ui-widget ui-corner-all" type="submit" 
name="email_last_weeks_report" value="Email Last Weeks Report Now" /> 
</form> 
+0

両方のif条件で同じことを解除しています –

+0

_ "ページの最後のボタンがクリックされた理由を理解していません" _ - ブラウザが正確に同じ要求をもう一度...それはリフレッシュが何を意味するのか_means_です。 _ "と、unsetコマンドがなぜ動作していないのか" _ - なぜなら、まずは無意味だからです。フォームを送信するときに最初に設定を解除することも同じです。つまり、その_did_が思ったとおりに機能すると、機能が最初から壊れることになります。 _identification_である2つの要求の間で_differentiate_を試みています...もちろん、動作できません。 – CBroe

答えて

2

ボタンをクリックすると、フォームが送信されます。

フォームのデータはバンドルされ、リクエストに含まれます。

脇:デフォルトのmethod=GETを使用していますが、あなたは「安全な」リクエストを行っていません。あなたは何かをしているだけでなく、を取得しています。を取得しています。 POSTリクエストを使用する必要があります。

[更新]をクリックすると、ブラウザに再度要求を行い、新しいバージョンのページを表示するように指示します。

リクエストには「特定のメールを送信する」というクエリ文字列が含まれているため、そのメールを再度送信します。ブラウザがその中に同じデータを持つ新しい要求したときので、$_REQUEST


設定解除値は効果がありません:$_REQUESTはちょうど再び埋めます。


あなたはthe PRG patternを使用してこの問題に対処する必要があります

  1. method=POSTは、PHPスクリプトのプロセスを持って使用してフォームを送信形式のデータ(電子メールを送信する)、その後をリダイレクト別のPHPスクリプト
  2. 新しいPHPスクリプトに結果を表示させます(この場合、結果はありません。そのフォームだけです。PHPがないプレーンなHTMLドキュメントをiで使用できます)。 t)。
+0

同じページにリダイレクトする方法や同じページに留まる方法はありませんか?これを回避してユーザーにクリックを強制するには、ランディングページを作成する必要があります。あなたがサリーにも再subitしたい場合は戻って現在にリダイレクトを追加すると尋ねるん:\t \tヘッダー(「場所:export_current_week.php」、trueの場合、301); \t \t出口(); – Reno

+0

私はこの方法で良いことをやって、ちょうど戻ってリンクして、「成功した電子メールで送信」予告ページに行く好きになりました。実際に過度に複雑化することなく、私を覚えて理解するのは簡単です。助けてくれてありがとう! – Reno

1

変更

<form> 

<form method='POST'> 

複数の送信を防止するための簡単な方法に隠された入力フォームにランダムなトークンを追加することです。

<input type='hidden' name='formtoken' value='<?= uniqueid() ?>'/> 

ページがサーバーからフェッチされるたびに、この隠し変数の値が変更されます。したがって、サーバー側では、この一意のIDを持つフォームが以前に送信されたかどうかをチェックすることによって、同じフォームが再送信されるのを防ぐことができます。

session_start(); 
$sessionToken = $_SESSION['formtoken']? : null; 
$currentToken = $_POST['formtoken']? : null; 

// If no session token yet: form has never been submitted 
if(!$sessionToken): 
    // save the current token in session so we'll recognize it next time 
    $_SESSION['formtoken'] = $currentToken; 
    /* ok to send the email */ 

// ElseIf current token was already used: Duplicate form submission 
elseif($sessionToken === $currentToken): 
    /* don't send the email!*/ 

// Else session token exists, but current token is new: User fetched a new form from server 
else: 
    // update the session token 
    $_SESSION['formtoken'] = $currentToken; 
    /* ok to send the email */ 

endif; 

ユーザーが更新すると、ブラウザはフォームを再送信するかどうかを尋ねます。もしそうなら、あなたは、現在のトークンとセッショントークンが同じであることを知っているでしょう。それをどう扱うかはあなた次第です。 (それはあなたが方法で使用すべき、最初のPOSTシナリオにお聞きしますが)GETやPOSTフォームにページを更新

+0

これで問題は解決しません。これは単に、リフレッシュをクリックしたときにページをリフレッシュするかどうかをブラウザに尋ねるよう促します。 – Quentin

+0

@クエンティン良い点。私は少しを追加するか、削除します。 – BeetleJuice

+0

ええ、それは私が得た行動でした。ページを更新する場合は、再送信、または同じページにフォームポストは、それが上だ場合、これは標準的な動作がある@Reno – Reno

1

は、データを再送信します。

は、フォームが

if(isset(...)){ 
    // Do your logic 
    header('Location: https://you_site.com/your-form-page?thank-you'); 
    exit; 
} 

を提出した後に何かがページに出力される前に、これを行わなければならないユーザーをリダイレクトしてください。

+0

POSTフォームではありません。 – Quentin

+0

他の回答の人は、フォームをPOSTにすると問題が解決すると言っています。それを参照していた。 – spaceman

+2

答えは質問に答えなければならない、彼らは他の答えに応答すべきではない。 – Quentin

関連する問題