2016-03-15 77 views
0

我父亲想要建立一个通讯调度系统,它提供了定制的字段作为定制系统的一部分。用户可以在文本中使用一些特殊变量来插入收件人的名称(等等)。让一个PHP脚本不断重定向到它自己,忽略浏览器超时

最后的HTML表单要求在电子邮件中会插入数据,以及一组收件人到数据库中的所有数据。然后用户被重定向到工作者脚本。

在工人脚本(我们称之为worker.php)他大致有以下几点:

# Get current job from the database. 
# Pop off the first recipient in the list. 
# Retrieve additional data about that recipient from the database. 
# Generate and send email. 
# Store truncated list of recipients in database. 

if (work_left) { 
    header('Location: worker.php'); 
} 
else { 
    header('Location: done.php'); 
} 

工人只做一个工作项,以躲避PHP时间限制。该系统将部署在共享托管服务器上,该托管服务器可能具有最神秘的php.ini设置。

它的工作原理是,处理工作项目并收缩数据库中的收件人数量。现在无法预料的问题是,浏览器最终会超时,取消连接。 PHP脚本然后被取消,没有更多的工作完成。通过将浏览器重新指向worker.php可轻松重启该流程,但这是最终用户不应该做的事情。

本网站快速搜索给我的ignore_user_abort功能,看起来很有希望,为了躲避浏览器超时。我担心在这种情况下这不能解决问题:浏览器会在某个时候关闭连接。当前正在运行的PHP脚本将完成运行,然后告诉浏览器重新加载worker.php。浏览器不再监听,进度也停止。这是一个改进,因为它不会中止交易,但不是解决方案。

另一个想法,我们已经用一个取代重定向到worker2.php。该PHP文件只包含重定向回worker.php。这对浏览器来说可能是足够的进步,它将继续加载并且不会超出超时(希望每个URL至少超时?)。

如果这样也行不通,那么使用<meta>的HTML重定向可能是另一种选择。然后,worker.php将实际完成加载,浏览器将能够完成请求。然后,<meta>将再次重定向到worker.php以执行下一个工作项目。最后一个缺点是它仍然依赖于浏览器打开。

在最好的情况下,他正在寻找一种解决方案,一旦它开始,它将贯穿始终。浏览器可能会超时,用户可能会关闭窗口,脚本仍然会通过并发送所有电子邮件。是否可以生成一个工作程序,使其不受PHP执行时间限制和浏览器超时的影响?

+0

如果你想让它继续运行,浏览器关闭后,您需要使用http://php.net/exec启动后台进程。在后台启动一个单独的PHP脚本,并_that_后台脚本可以完全删除超时并运行,只要它需要。 – jszobody

+0

在后台执行另一个php进程,或'fork()'当前进程。要么将独立于网络服务器,并且不会受到用户在其结束时做的任何事情的影响。 –

+0

@jszobody:我认为应该用'exec('/ usr/bin/php path/to/worker.php')生成单独的PHP进程;'?很可能这是不可能的共享主机(没有额外付款),所以我们将需要检查。如果一个人执行'exec',当PHP脚本被超时杀死时它不会被杀死,是吗? –

回答

0

可能不是依靠共享主机上的花哨背景脚本,而是使用crontab(即使你的主机提供商不给你一个你可以使用一些服务,这将允许你模拟cron),它将每分钟触发一次脚本(?)。脚本会检查队列表中是否有一些工作,选择一些(尽可能多的服务器将允许您处理)并将已处理的任务标记为已完成(或从表格中删除它们)。然后,您可以提供一些可供发件人访问的端点以查看其进度(计算用户的所有任务以及标记为已完成的任务)。 我不认为你能够在碎片上使用RabbitMQ + supervisord或类似的东西,但我不认为使用后台php脚本是个好主意:)