提交表单后如何在后台运行 PHP 脚本?
问题
我有一个表单,当提交时,它将运行基本代码来处理提交的信息并将其插入数据库以显示在通知网站上.此外,我还有一份已注册通过电子邮件和 SMS 消息接收这些通知的人员列表.该列表目前微不足道(仅推送约 150 条),但足以导致需要一分钟以上的时间来循环浏览整个订阅者表并发送 150 多封电子邮件.(由于邮件群发政策,我们的电子邮件服务器的系统管理员要求这些电子邮件是单独发送的.)
Problem
I have a form that, when submitted, will run basic code to process the information submitted and insert it into a database for display on a notification website. In addition, I have a list of people who have signed up to receive these notifications via email and SMS message. This list is trivial as the moment (only pushing about 150), however it's enough to cause it takes upwards of a minute to cycle through the entire table of subscribers and send out 150+ emails. (The emails are being sent individually as requested by the system administrators of our email server because of mass email policies.)
在此期间,发布警报的个人将在表单的最后一页停留近一分钟,而没有任何积极强化他们的通知正在发布.这会导致其他潜在问题,所有可能的解决方案我都觉得不太理想.
During this time, the individual who posted the alert will sit on the last page of the form for almost a minute without any positive reinforcement that their notification is being posted. This leads to other potential problems, all that have possible solutions that I feel are less than ideal.
首先,发帖者可能认为服务器滞后并再次单击提交"按钮,导致脚本重新开始或运行两次.我可以通过使用 JavaScript 禁用按钮并将文本替换为处理中..."之类的内容来解决此问题,但这并不理想,因为用户仍会在脚本执行期间卡在页面上.(另外,如果 JavaScript 被禁用,这个问题仍然存在.)
First, the poster might think the server is lagging and click the 'Submit' button again, causing the script to start over or run twice. I could solve this by using JavaScript to disable the button and replace the text to say something like 'Processing...', however this is less than ideal because the user will still be stuck on the page for the length of the script execution. (Also, if JavaScript is disabled, this problem still exists.)
其次,发帖人可能会在提交表单后过早关闭标签页或浏览器.脚本将继续在服务器上运行,直到它尝试写回浏览器,但是如果用户随后浏览到我们域中的任何页面(当脚本仍在运行时),浏览器会挂起加载页面,直到脚本结束.(这只发生在浏览器的一个选项卡或窗口关闭时,而不是整个浏览器应用程序关闭时.)不过,这并不理想.
Second, the poster might close the tab or the browser prematurely after submitting the form. The script will keeping running on the server until it tries to write back to the browser, however if the user then browses to any page within our domain (while the script is still running), the browser hangs loading the page until the script has ended. (This only happens when a tab or window of the browser is closed and not the entire browser application.) Still, this is less than ideal.
(可能的)解决方案
我决定将脚本的电子邮件"部分拆分为一个单独的文件,以便在发布通知后调用.我本来想在通知成功发布后将其放在确认页面上.但是,用户不会知道这个脚本正在运行,并且任何异常对他们来说都不会很明显;此脚本不会失败.
(Possible) Solution
I've decided I want to break out the "email" part of the script into a separate file I can call after the notification has been posted. I originally thought of putting this on the confirmation page after the notification has been successfully posted. However, the user will not know this script is running and any anomalies will not be apparent to them; This script cannot fail.
但是,如果我可以将此脚本作为后台进程运行呢?所以,我的问题是:如何执行 PHP 脚本以作为后台服务触发并完全独立于用户在表单级别执行的操作?
But, what if I can run this script as a background process? So, my question is this: How can I execute a PHP script to trigger as a background service and run completely independent of what the user has done at the form level?
这个不能被cron'ed.它必须在表单提交的那一刻运行.这些是高优先级通知.此外,运行我们服务器的系统管理员不允许 cron 运行频率超过 5 分钟.
This cannot be cron'ed. It must run the instant the form is submitted. These are high-priority notifications. In addition, the system administrators running our servers disallow crons from running any more frequently than 5 minutes.
推荐答案
用 exec
和 shell_exec
做一些实验我发现了一个完美的解决方案!我选择使用 shell_exec
这样我就可以记录每个发生(或不发生)的通知过程.(shell_exec
作为字符串返回,这比使用 exec
更容易,将输出分配给变量,然后打开要写入的文件.)
Doing some experimentation with exec
and shell_exec
I have uncovered a solution that worked perfectly! I choose to use shell_exec
so I can log every notification process that happens (or doesn't). (shell_exec
returns as a string and this was easier than using exec
, assigning the output to a variable and then opening a file to write to.)
我正在使用以下行来调用电子邮件脚本:
I'm using the following line to invoke the email script:
shell_exec("/path/to/php /path/to/send_notifications.php '".$post_id."' 'alert' >> /path/to/alert_log/paging.log &");
注意命令末尾的 &
很重要(正如@netcoder 指出的那样).此 UNIX 命令在后台运行一个进程.
It is important to notice the &
at the end of the command (as pointed out by @netcoder). This UNIX command runs a process in the background.
脚本路径后用单引号括起来的额外变量设置为我可以在脚本中调用的 $_SERVER['argv']
变量.
The extra variables surrounded in single quotes after the path to the script are set as $_SERVER['argv']
variables that I can call within my script.
然后,电子邮件脚本使用 >>
输出到我的日志文件,并将输出如下内容:
The email script then outputs to my log file using the >>
and will output something like this:
[2011-01-07 11:01:26] Alert Notifications Sent for http://alerts.illinoisstate.edu/2049 (SCRIPT: 38.71 seconds)
[2011-01-07 11:01:34] CRITICAL ERROR: Alert Notifications NOT sent for http://alerts.illinoisstate.edu/2049 (SCRIPT: 23.12 seconds)
相关文章