我有一个PHP脚本,它将消息发送到我在Heroku中托管的用户列表。现在我想在这些消息之间添加延迟。比如说,每条消息之间有6分钟的差距。因此,如果有90个用户,该脚本应该在后台运行9个小时。
我尝试使用ajax调用此脚本,因此它在后台运行并在for循环中添加sleep(360);
,以获得6分钟的延迟。但它只适用于大约10到20个用户,之后就停止了。
foreach ($users_list["users"] as $key => $value) {
try{
....
code for sending message
.....
}catch(Exception $e){
continue;
}
sleep(360);
}
所以我想知道,在Heroku中实现这一目标的最佳方法是什么。
答案 0 :(得分:2)
使用AJAX调用脚本并不会在"背景"中调用它。它只是从你所在的页面异步运行它。换句话说,它仍然在Apache中运行,有任何会话数据,并且仍然受到PHP和Apache的超时设置的约束。
要在后台真正运行它,您可以使用CRON
之类的内容或者,如果允许您在服务器上,可以通过命令行调用它,例如exec
或shell_exec
,还有一些其他类似功能,例如popen
, system
等等。他们都以稍微不同的方式做事。
某些环境因素会有所不同,这可能会对您的代码产生重大影响。例如,$_SERVER
中的很多内容未设置或具有不同的信息。例如服务器IP地址可能不在那里,你不会有任何会话内容。您无法使用$_GET
或$_POST
,但可以从$argv
数组获取输入数据(来自命令行调用),第一项是文件路径......等......
基本上你需要这样称呼它:
exec('php -f "path/to/php/file.php" "arg1" "arg2"');
以这种方式调用它仍然会阻塞,这意味着它等待执行被调用的脚本。
要更进一步并使其成为非阻止,您可以添加(在Linux上)
exec('php -f "path/to/php/file.php" "arg1" "arg2" > /dev/null &');
最后&
是最重要的一点。
现在在Windows上它有点不同的球赛。我使用这个
取得了成功$WshShell = new \COM('WScript.Shell');
$cmd = 'cmd /C php "path/to/php/file.php" "arg1" "arg2"';
$WshShell->Run($cmd, 0, false);
同样在Windows上运行只有php
的PHP,您必须添加php.exe
yhou想要用于path
环境变量的路径。否则,您必须使用exe
的完整路径,而不仅仅是php
在任何一种情况下,您都应该非常小心地将最终用户数据放入任何命令行调用中。有2个功能可以消毒它,但我试着不把它放进去。
我为此编写了一个包装类,您可以在GitHub
上找到希望它有所帮助。