如何使长时间运行的PHP脚本立即显示成功消息?

4

目标

我正在尝试创建一个 PHP 脚本,通过 PHP Mailer 实例将大小为 6MB 的 PDF 文件电子邮件发送给网站上请求的用户。用户在表单中输入他们的电子邮件地址,提交表单,然后文件通过 PHP 邮件程序实例发送到他们那里。用户在提交表单后显示成功页面。

问题

通过 POST 方法提交数据后,会有一段时间的长暂停,服务器最终返回一个404错误。但是,在几分钟后,电子邮件附件可以完美地接收到。

故障排除/尝试的解决方案

我认为这个问题是因为 PHP Mailer 所需的时间太长了,以至于无法发送带有大附件的电子邮件。服务器超时并返回 404。在此期间,脚本最终完成处理,然后才会接收电子邮件。

如果我删除附件并只发送一个空电子邮件,脚本将非常快速地加载并显示成功/确认页面。

我考虑过创建重定向,但是无论我找到的关于如何在 PHP 中实现重定向的解释都说您应该关闭原始脚本(这不是我想要的)。

问题

我如何允许电子邮件脚本运行一段时间,同时立即向用户显示成功消息,以使他们不会感到困惑?


在您的php.ini文件中。尝试更改max_execution_time。 - Mistergreen
5个回答

1
这是一个消息队列的任务。将发送邮件所需的所有信息存储在队列中,并有一个后台任务获取此信息并发送您的邮件。如果成功将消息插入到消息队列中,请向用户显示成功消息。
如果您无法访问后台脚本(例如共享主机),仍然可以直接响应。只需使用ignore_user_abort(true)并发送正确的Content-Length头即可。浏览器将信任该标头并显示响应,而您的脚本可以继续运行并发送邮件。

1
另一个解决方案:不要立即在电子邮件中附加大文件,而是给他们PDF文件的下载链接。这样,内容会变得更加简短,但没有附件。
您可以努力创建唯一的URL,以供不同用户下载相同的PDF文件。
否则,邮件排队是很好的解决方法,如前所述。

0

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


0

由于没有提供代码,您可以使用AJAX调用脚本并在任何位置显示成功消息。脚本将被调用,用户将收到消息,并且一旦脚本完成,用户将收到电子邮件。

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


0

这是使用异步作业队列(例如GearmanBeanstalk)的一个很好的用例。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接