Mic*_*yen 97 php scripting background
问题
我有一个表单,在提交时,将运行基本代码来处理提交的信息并将其插入数据库以显示在通知网站上.另外,我有一个已经注册通过电子邮件和短信接收这些通知的人员列表.这个列表是微不足道的(只推动了大约150个),但这足以导致需要花费一分钟才能在整个订阅者表中循环并发送150多封电子邮件.(由于大量的电子邮件策略,电子邮件按照我们的电子邮件服务器的系统管理员的要求单独发送.)
在此期间,发布提醒的个人将在表格的最后一页上停留近一分钟而没有任何正面强化他们的通知被发布.这导致了其他潜在的问题,所有这些问题都有可能我认为不太理想的解决方案.
首先,海报可能认为服务器滞后并再次单击"提交"按钮,导致脚本重新开始或运行两次.我可以通过使用JavaScript来禁用按钮并将文本替换为"正在处理..."之类的内容来解决这个问题,但这并不理想,因为用户在脚本执行的长度上仍会卡在页面上.(另外,如果禁用JavaScript,则此问题仍然存在.)
其次,海报可能会在提交表单后过早关闭标签页或浏览器.该脚本将继续在服务器上运行,直到它尝试写回浏览器,但是如果用户随后浏览到我们域中的任何页面(当脚本仍在运行时),则浏览器会挂起加载页面,直到脚本结束.(仅当浏览器的选项卡或窗口关闭而不是整个浏览器应用程序时才会发生这种情况.)但这仍然不太理想.
(可能)解决方案
我已经决定将脚本的"电子邮件"部分分解为一个单独的文件,我可以在发布通知后调用它.我最初想到在通知成功发布后将其放在确认页面上.但是,用户不会知道此脚本正在运行,并且任何异常都不会对他们显而易见; 这个脚本不会失败.
但是,如果我可以将此脚本作为后台进程运行,该怎么办?所以,我的问题是:我如何执行PHP脚本作为后台服务触发并完全独立于用户在表单级别完成的操作?
编辑:这不能是cron'ed.它必须在提交表单的瞬间运行.这些是高优先级通知.此外,运行我们服务器的系统管理员不允许运行任何超过5分钟的crons.
Mic*_*yen 83
做了一些实验用exec和shell_exec我已经揭露了完美工作的解决方案!我选择使用,shell_exec所以我可以记录发生(或不发生)的每个通知过程.(shell_exec以字符串形式返回,这比使用更容易exec,将输出分配给变量,然后打开要写入的文件.)
我正在使用以下行来调用电子邮件脚本:
shell_exec("/path/to/php /path/to/send_notifications.php '".$post_id."' 'alert' >> /path/to/alert_log/paging.log &");
Run Code Online (Sandbox Code Playgroud)
注意&命令的结尾很重要(正如@netcoder所指出的那样).此UNIX命令在后台运行进程.
在脚本路径之后用单引号括起来的额外变量被设置为$_SERVER['argv']我可以在我的脚本中调用的变量.
然后,电子邮件脚本使用输出到我的日志文件>>,并将输出如下内容:
[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)
Run Code Online (Sandbox Code Playgroud)
net*_*der 18
在Linux/Unix服务器上,您可以使用proc_open在后台执行作业:
$descriptorspec = array(
array('pipe', 'r'), // stdin
array('file', 'myfile.txt', 'a'), // stdout
array('pipe', 'w'), // stderr
);
$proc = proc_open('php email_script.php &', $descriptorspec, $pipes);
Run Code Online (Sandbox Code Playgroud)
这&是重要的一点.即使原始脚本已结束,脚本也将继续.
在所有答案中,没有人考虑过非常简单的fastcgi_finish_request函数,该函数在被调用时会将所有剩余输出刷新到浏览器并关闭Fastcgi会话和HTTP连接,同时让脚本在后台运行。
一个例子:
<?php
header('Content-Type: application/json');
echo json_encode(['ok' => true]);
fastcgi_finish_request(); // The user is now disconnected from the script
// do stuff with received data,
Run Code Online (Sandbox Code Playgroud)
为什么不在脚本上发出HTTP请求而忽略响应呢?
http://php.net/manual/en/function.httprequest-send.php
如果您在脚本上发出请求,则需要调用您的Web服务器将在后台运行它,您可以(在主脚本中)显示一条消息,告诉用户脚本正在运行.
小智 5
在后台运行 PHP 脚本的更简单方法是
php script.php >/dev/null &
Run Code Online (Sandbox Code Playgroud)
该脚本将在后台运行,页面也将更快地到达操作页面。
| 归档时间: |
|
| 查看次数: |
131903 次 |
| 最近记录: |