在heroku的后台长时间运行php脚本

在heroku的后台长时间运行php脚本,php,heroku,backgroundworker,taskscheduler,Php,Heroku,Backgroundworker,Taskscheduler,我有一个PHP脚本,它将消息发送到一个用户列表,我在Heroku中托管了该列表。现在我想在这些消息之间添加一个延迟。比如说,每条消息之间有6分钟的间隔。因此,如果有90个用户,该脚本应该在后台运行9个小时 我尝试使用ajax调用这个脚本,因此它在后台运行,并添加sleep(360)在for循环内,以获得6分钟的延迟。但它只适用于大约10到20个用户,然后停止 foreach ($users_list["users"] as $key => $value) { try{

我有一个PHP脚本,它将消息发送到一个用户列表,我在Heroku中托管了该列表。现在我想在这些消息之间添加一个延迟。比如说,每条消息之间有6分钟的间隔。因此,如果有90个用户,该脚本应该在后台运行9个小时

我尝试使用ajax调用这个脚本,因此它在后台运行,并添加
sleep(360)在for循环内,以获得6分钟的延迟。但它只适用于大约10到20个用户,然后停止

foreach ($users_list["users"] as $key => $value) {
        try{
            ....
            code for sending message
             .....

        }catch(Exception $e){
            continue;
        }
        sleep(360);
    }

所以我想知道,在Heroku实现这一目标的最佳方式是什么

使用AJAX调用脚本并不是在“后台”中调用它,而是从您所在的页面异步运行它。换句话说,它仍然在Apache中运行,有任何会话数据,并且仍然受PHP和Apache的超时设置的约束

要在后台真正运行它,您可以使用

或者,如果允许您在服务器上调用它,您可以通过命令行调用它,如使用
exec
shell\u exec
,还有一些其他类似的功能,如
popen
system
等。它们的工作方式都略有不同

一些环境因素会有所不同,这可能会对代码产生很大影响。例如,
$\u服务器
中的许多内容未设置或具有不同的信息。例如,服务器IP地址可能不在其中,您将不会有任何会话内容。您将无法使用
$\u GET
$\u POST
,但可以从
$argv
数组中获取输入数据(来自命令行调用),第一项是文件路径。。。等等

基本上你需要这样称呼它:

 exec('php -f "path/to/php/file.php" "arg1" "arg2"');
以这种方式调用它仍然会被阻塞,这意味着它将等待被调用脚本的执行

要更进一步并使其非阻塞,您可以添加(在Linux上)

末尾的
&
是最重要的位

现在在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
y环境变量中。否则,您必须使用
exe
的完整路径,而不仅仅是
php

无论哪种情况,在任何命令行调用中放置最终用户数据时都应该非常小心。有两个函数可以清理它,但我尽量不把它放进去

我为此编写了一个包装器类,您可以在我的


希望有帮助。

Ajax不会让它在后台运行,因为它仍然在Apache下运行,您必须通过
exec
shell\u exec
甚至
CRON
之类的方式调用它。这是我编写的一个后台执行脚本,请小心使用任何最终用户数据作为命令行调用的一部分。另外,我应该提到,很多时候PHP都会使用单独的
ini
配置文件作为命令行调用的一部分,这可能会也可能不会启用了不同的扩展。这在heroku中可以工作吗?我没有,所以我不知道。您可以通过命令行(SSH)访问它并运行PHP吗?例如,您可以在SSH会话中执行
php-v
。你用过CRON吗?我从来没见过Heroku,他们让你做CRON工作吗
$WshShell = new \COM('WScript.Shell');
$cmd = 'cmd /C php "path/to/php/file.php" "arg1" "arg2"';
$WshShell->Run($cmd, 0, false);