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

时间:2018-04-06 18:50:46

标签: php heroku backgroundworker taskscheduler

我有一个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中实现这一目标的最佳方法是什么。

1 个答案:

答案 0 :(得分:2)

使用AJAX调用脚本并不会在"背景"中调用它。它只是从你所在的页面异步运行它。换句话说,它仍然在Apache中运行,有任何会话数据,并且仍然受到PHP和Apache的超时设置的约束。

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

之类的内容

或者,如果允许您在服务器上,可以通过命令行调用它,例如execshell_exec,还有一些其他类似功能,例如popensystem等等。他们都以稍微不同的方式做事。

某些环境因素会有所不同,这可能会对您的代码产生重大影响。例如,$_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个功能可以消毒它,但我试着不把它放进去。

escapeshellarg

escapeshellcmd

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

上找到

希望它有所帮助。