如果刷新页面,PHP按钮调用函数将导致函数重复

时间:2017-08-24 14:00:37

标签: php

我有两个简单的HTML表单按钮,可以调用PHP函数来发送电子邮件。除了一件事,一切都很好。如果单击其中一个按钮发送报告,然后刷新页面,则该功能似乎再次被调用,并且用户使用浏览器刷新按钮刷新页面并再次发送电子邮件。

如果页面被刷新,电子邮件将再次出现,点击最后一个按钮。因此,如果我单击按钮1然后刷新页面,我将获得按钮1的两个报告。如果我单击按钮#1,然后单击按钮#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> 

3 个答案:

答案 0 :(得分:2)

点击按钮提交表单。

表单中的数据捆绑在一起并包含在请求中。

除此之外:您使用method=GET作为默认设置,但您并没有使用&#34;安全&#34;请求。您正在某些事情,而不仅仅是获取信息。您应该使用POST请求。

点击刷新后,告诉浏览器再次发出请求并显示该页面的新版本。

由于请求包含查询字符串,该字符串显示&#34;发送特定电子邮件&#34;,它会再次发送该电子邮件。

$_REQUEST中的取消设置值无效,因为当浏览器发出包含相同数据的请求时:$_REQUEST只会再次填满。

您应该使用the PRG pattern处理此问题:

  1. 使用method=POST
  2. 提交表单
  3. 让您的PHP脚本处理表单中的数据(即发送电子邮件),然后重定向到另一个PHP脚本
  4. 让新的PHP脚本显示结果(在这种情况下,没有结果,只是表单,您可以使用没有PHP的纯HTML文档)。

答案 1 :(得分: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;

当用户刷新时,浏览器会询问她是否要重新提交表单。如果她这样做,你会知道,因为当前令牌和会话令牌将是相同的。由你决定如何处理它。

答案 2 :(得分:1)

使用GET或POST表单刷新页面将重新提交数据(尽管它会在POST方案中首先询问您,顺便说一下,您应该使用它。)

尝试在表单提交后重定向用户

NUM

必须在页面上输出任何其他内容之前完成此操作。