提交表单后如何在后台运行PHP脚本?

2022-01-04 00:00:00 background php scripting

问题
我有一个表单,当提交时,它将运行基本代码来处理提交的信息并将其插入数据库以在通知网站上显示.此外,我有一份已注册通过电子邮件和 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.

  1. 首先,发布者可能认为服务器滞后并再次单击提交"按钮,导致脚本重新开始或运行两次.我可以通过使用 JavaScript 禁用按钮并替换文本以说出诸如正在处理..."之类的内容来解决此问题,但是这不太理想,因为用户在脚本执行期间仍会停留在页面上.(另外,如果 JavaScript 被禁用,这个问题仍然存在.)

  1. 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 运行频率超过 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.

推荐答案

使用 execshell_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)

相关文章