【问题标题】:No way back, stop PHP redoing everything if user hits refresh?没有办法,如果用户点击刷新,停止 PHP 重做所有事情?
【发布时间】:2012-01-19 06:53:38
【问题描述】:

我是初级 PHP 开发人员,目前正在制作一份报价单,该表格将包含客户详细信息以及员工在报价单中输入的任何内容,并将:

  • 将客户和报价详情保存到数据库。
  • 生成 PDF(使用 mpdf 库)
  • 将 pdf 通过电子邮件发送给客户

目前它只有两个文件 index.phpquote.php

这是一个图表

http://i.imgur.com/UDnLq.png

如您所见,它是一个单体架构(我将所有操作都放在一个 PHP 文件中)。

这会导致问题,因为当用户点击“提交”并且 quote.php 执行其所有功能时,用户会卡在该页面上。然后,如果他们点击 Refresh ,quote.php 将再次重新执行,它最终会向我的数据库表和电子邮件收件箱发送垃圾邮件。

我想知道什么是防止用户重新执行或返回做应该只做一次的事情的最佳方法。

我有几个想法,希望你能提出你的建议?

  • 想法 1:防止重复执行相同代码的会话变量。

  • 想法 2:将 quote.php 文件分解为单独的文件并从每个文件中跳转。 (这可能吗)?

我想以最好的方式做到这一点,我愿意接受任何建议!

感谢您的宝贵时间!

:)

【问题讨论】:

  • 我认为最好使用会话变量

标签: php forms refresh


【解决方案1】:

您要执行的操作称为 PRG 或 Post/Redirect/Get。在成功 POST 请求后,您通过Location 标头重定向到另一个页面。此页面将仅显示某些内容(例如状态消息),但不会执行任何操作。然后按 F5 将重新加载该页面,而不是再次执行 POST 请求。

显然它在没有 POST 的情况下也可以工作,但使用 GET 来修改事物的操作无论如何都不是一个好主意。

【讨论】:

  • 这听起来很有趣,你能给我链接一些代码示例或资源吗!谢谢:)
  • 您只需在操作完成后header('Location: othersite.php'); exit;即可。
【解决方案2】:

如果一切正确,您可以发送标题:

header('Location: http://www.yourdomain.com/another_page.php');

然后跳转到另一个页面

【讨论】:

    【解决方案3】:

    保存客户详细信息后,重定向到其他页面,例如感谢页面。此外,您可以在成功操作后在会话中存储一个标志,如quote_submitted = 1。然后当刷新或提交时,检查它,以避免循环操作。

    否则,您有什么方法可以存储一些客户 ID 吗?然后您可以查看天气客户是否保存了他的记录,因此不会重复提交。

    【讨论】:

    • 我的表中有一个名为“quote”的列,它是(是/否),因为有时我们可能只是保存不想要立即报价的客户详细信息。 :)
    • 那么,如果报价为“是”,则什么也不做。但是,如果报价为“否”,则接受报价,将其存储并通过将该客户的报价列值更改为“是”来更新该客户的记录。因此,下次他/她尝试时,我们不会进行重复操作。我认为这有帮助。 :)
    【解决方案4】:

    首先,您应该在提交表单后重定向到不同的页面。该页面通常指示成功或失败。由于没有什么可以阻止访问者返回表单页面并再次提交,因此使用会话变量是防止重新执行的最佳选择。虽然它不是万无一失的,因为会话在浏览器关闭时过期,但它确实可以防止意外重新提交。

    【讨论】:

      【解决方案5】:

      如果表单需要一段时间来处理(PDF 生成可能需要时间),那么好的第一步是阻止用户重新提交表单。使用 javascript 禁用提交按钮,并可能显示一个加载图标,以便他们知道发生了什么事。

      一旦代码完成执行,您需要将它们重定向到另一个页面,这样您就不会遇到刷新页面的问题。

      这个很简单,发个header就行了……

      // do PDF and email code
      // now redirect user to thank you page
      header("Location: thank_you.php");
      exit();
      

      【讨论】:

      • 那么我需要用一些html等创建一个名为thank_you.php的新php文件吗? :)
      • 是的,这将是最好的事情
      【解决方案6】:

      一种可能性是,实现后重定向获取方法。

      简单地说,一个 POST 请求永远不会传递给浏览器。相反,您执行所有必要的操作并将所需的信息存储在会话中,然后使用代码 303 进行重定向。

      $page = 'quote_done.php';
      header('Location: '.$page, true, 303);
      exit;
      

      这样做,浏览器将显示“quote_done.php”页面(一个 GET 请求),而不是使用 POST 请求的页面。这也是添加到历史记录的页面,因此刷新和使用后退按钮将永远不会执行另一个 POST 请求。作为一个很好的副作用,您可以摆脱关于重新发送数据的浏览器警告,通常用户无法决定接下来要做什么。

      我认为这种方法的最大问题是,您需要一个会话来存储错误消息,这意味着您必须依赖 cookie。如果不重定向显示错误,浏览器会显示关于重新发送数据的警告。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-12-19
        • 2022-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-09
        • 1970-01-01
        相关资源
        最近更新 更多