为什么我的Heroku后台脚本会过早停止?

nzrxty8p  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(146)

我有一个托管在Heroku中的PHP脚本,它可以向用户列表发送消息。现在我想在这些消息之间添加一个延迟;每条信息之间有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);
    }

为什么会停下来?我如何让它为完整的用户列表运行?

kuhbmx9i

kuhbmx9i1#

使用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的路径添加到path环境变量中。否则,您必须使用exe的完整路径,而不仅仅是php
在任何一种情况下,您都应该非常小心地将最终用户数据放在任何命令行调用中。有两个功能来消毒它,但我试着不把它放进去:

我为此写了一个 Package 器类,你可以在我的GitHub上找到

相关问题