【问题标题】:How do you make a long-running PHP script display a success message immediately?如何让长时间运行的 PHP 脚本立即显示成功消息?
【发布时间】:2015-08-22 18:26:14
【问题描述】:

目标

我正在尝试创建一个 PHP 脚本,该脚本通过电子邮件将一个相当大 (6MB) 的 PDF 文件发送给请求它的网站上的用户。用户在表单中输入他们的电子邮件地址,提交表单,然后文件通过 PHP Mailer 实例发送给他们。用户在提交表单时会显示一个成功页面。

问题

通过 POST 方法提交数据后,有很长时间的停顿,服务器最终返回 404。但是,几分钟后,带有 PDF 附件的电子邮件完全正常接收。

疑难解答/尝试的解决方案

我将问题归咎于 PHP Mailer 只是因为附件过大而导致发送电子邮件的时间过长。服务器超时并求助于返回 404。与此同时,脚本最终完成处理并随后收到电子邮件。

如果我删除附件并只发送一封空白电子邮件,脚本会很快加载并显示成功/确认页面。

我考虑过创建一个重定向,但是我在任何地方都找到了关于如何在 PHP 中实现重定向的解释,据说你应该杀死原始脚本(我不想这样做)。

问题

如何让电子邮件脚本花时间运行,同时立即向用户显示成功消息,以免他们感到困惑?

【问题讨论】:

标签: php html phpmailer


【解决方案1】:

这是一个消息队列的任务。将发送邮件所需的所有信息存储在队列中,并让后台任务获取此信息并发送邮件。如果插入消息队列成功,则向用户显示成功消息。

如果您无权访问后台脚本(例如共享主机),您仍然可以直接响应。只需使用 ignore_user_abort(true) 并发送正确的 Content-Length 标头即可。浏览器将信任该标头并显示响应,而您的脚本可以继续运行并发送邮件。

【讨论】:

    【解决方案2】:

    另一个解决方案:做一个快速的技巧,而不是立即在电子邮件中附加一个大文件。给他们 PDF 文件的下载链接。因此内容变得太短。但没有附件。

    您可以努力创建唯一的 URL 以供不同用户下载相同的 PDF 文件。

    如前所述,否则,电子邮件排队很好。

    【讨论】:

      【解决方案3】:

      不要立即通过电子邮件发送文件,而是将请求存储在数据库中,其中包含发送所需的所有详细信息。然后,您可以使用 cronjob/scheduled 任务定期(如果您愿意,每分钟)检查数据库是否有任何未完成的请求,并在后台发送电子邮件。

      【讨论】:

        【解决方案4】:

        由于没有提供任何代码,您可以使用 AJAX 调用您的脚本并在任何您想要的地方显示成功消息。脚本将被调用,用户将收到消息,脚本完成后,用户将收到电子邮件。

        当然,成功消息不应该在 AJAX 处理程序中实现,否则消息也会延迟。

        【讨论】:

          【解决方案5】:

          这是异步作业队列的一个很好的用例,例如 GearmanBeanstalk

          您必须运行一个外部工作进程,该进程将等待来自作业服务器的任务。
          在Web服务器端,只需创建任务,将其发送到作业服务器以将其分派给工作进程,然后退出PHP脚本。
          然后,工作进程将继续发送邮件,而 Web 服务器可以继续处理 HTTP 请求。

          【讨论】:

            猜你喜欢
            • 2023-03-20
            • 2019-12-17
            • 1970-01-01
            • 2017-09-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多