【问题标题】:How can I make a php script to run forever with Cron Job?如何使 php 脚本与 Cron Job 一起永久运行?
【发布时间】:2023-04-05 16:52:02
【问题描述】:
<?php
 while(true){
 //code goes here.....
 }
  ?>

我想制作一个 PHP 网络服务器,那么如何使用 Curl 让这个脚本永远运行呢?

【问题讨论】:

  • 您需要的是while(true),是的,它会一直运行直到发生某些事情(最好是由于您指定的中断条件)
  • @AdnanShammout 它会在一段时间后自动终止。 PHP 有一个内置的最大执行时间,除非您在代码中修改该设置。
  • @DexterHuinda,PHP 执行限制仅适用于从 Web 浏览器运行时。作为命令php server.php 运行时,限制不适用。为什么有人想从 Web 浏览器永远运行服务器?
  • @AdnanShammout 一个嵌入式 java 程序,applet 可以在浏览器中永久运行,并且您可以通过浏览器直接访问管理界面。大多数人负担不起在可以直接访问 shell 的服务器上托管,因此基于浏览器的实现是一种选择。
  • 需要注意的是,这会消耗 CPU,因为while(true) 使 CPU 执行指令,例如:cmp 永远。如果没有真正的工作要做,请考虑在循环中休眠。

标签: php


【解决方案1】:

不要忘记将最大执行时间设置为无限(0)。

最好确保不要运行多个实例,如果这是您的意图:

ignore_user_abort(true);//if caller closes the connection (if initiating with cURL from another PHP, this allows you to end the calling PHP script without ending this one)
set_time_limit(0);

$hLock=fopen(__FILE__.".lock", "w+");
if(!flock($hLock, LOCK_EX | LOCK_NB))
    die("Already running. Exiting...");

while(true)
{

    //avoid CPU exhaustion, adjust as necessary
    usleep(2000);//0.002 seconds
}

flock($hLock, LOCK_UN);
fclose($hLock);
unlink(__FILE__.".lock");

如果在 CLI 模式下,只需运行文件。

如果在网络服务器上的另一个 PHP 中,您可以启动一个必须像这样无限运行的 PHP(而不是使用 cURL,这消除了依赖性):

$cx=stream_context_create(
    array(
        "http"=>array(
            "timeout" => 1, //at least PHP 5.2.1
            "ignore_errors" => true
        )
    )
);
@file_get_contents("http://localhost/infinite_loop.php", false, $cx);

或者你可以像这样使用 wget 从 linux cron 开始:

`* * * * * wget -O - http://localhost/infinite_loop.php`

或者您可以从 Windows 调度程序开始,使用 bitsadmin 运行一个包含以下内容的 .bat 文件:

bitsadmin /create infiniteloop
bitsadmin /addfile infiniteloop http://localhost/infinite_loop.php
bitsadmin /resume infiniteloop

【讨论】:

  • 添加了 ignore_user_abort 以确保脚本不会因为调用者在 Web 环境中放弃请求而结束。
  • @Tiberiu-IonuțStan,那么当您需要时,您如何实际终止请求?
  • @Tiberiu-IonuțStan,你是什么意思?
  • @pacerier 作为一名程序员,您会预见到需要根据某些条件甚至外部标志自动终止,并将其放入beeing 运行代码(insinde infinite_loop.php)中。跨度>
  • @Tiberiu-IonuțStan,是的,但总会有错误。你的意思是说我们没有方法可以终止一个rouge脚本吗?
【解决方案2】:

要让 php 代码永远运行,它应该有 ff.:

  • set_time_limit(0); // 所以 php 不会正常终止,如果你要做的事情需要很长的处理时间
  • 保持页面活动的处理程序[通常通过设置客户端脚本以间隔调用同一页面]见setInterval()setTimeout()

编辑: 但是由于您将设置一个 cron 作业,因此您可以远离客户端处理。

编辑: 我的建议是不要使用无限循环,除非你有一个代码告诉它在一段时间后退出循环。请记住,您将使用 cron 作业调用同一页面,因此保持循环无限是没有意义的。 [编辑] 否则,您将需要@Tiberiu-Ionuț Stan 建议的锁定系统,因此每次调用 cron 作业时只能运行 1 个实例。

【讨论】:

    【解决方案3】:

    默认情况下不会,因为 PHP 有执行时间限制。 见:http://www.php.net/manual/en/info.configuration.php#ini.max-execution-time

    您可以通过设置值或在脚本中调用set_time_limit 使其永久运行 (http://php.net/manual/en/function.set-time-limit.php)。

    但我不建议这样做,因为 PHP(由 HTTP 请求调用)并非设计为具有无限循环。如果可以,请改用本地脚本,或定期请求页面以频繁执行任务。

    如果您的网站经常被其他人浏览,您可以改为在每个页面中都这样做。

    (想象一下,如果有人多次请求该脚本,您将运行多个实例)

    【讨论】:

    • 这仅适用于从网络浏览器运行时
    • @AdnanShammout 他说curl 所以最好的猜测是从HTTP请求运行
    • 您能指导我完成推理过程吗?我看不出curl 会如何指示从网络浏览器运行。
    • @AdnanShammout 我的错,我应该定义 HTTP 请求而不是“网络浏览器”
    • 再说一次,我不明白使用curl 意味着您是从HTTP 请求运行的!你确定你知道curl 的工作原理吗? Curl 将帮助您在脚本内发出 HTTP 请求,它与您如何运行该脚本(HTTP 请求或命令行)没有任何关系
    【解决方案4】:

    只有在脚本中设置 set_time_limit(0) 才能实现,否则在配置中设置 ma​​x_execution_time 后它将停止执行。

    而您正在使用 while(true) 条件,这将使您的脚本始终运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-09
      • 1970-01-01
      • 2012-06-27
      • 1970-01-01
      • 2011-05-28
      • 1970-01-01
      • 2018-03-22
      相关资源
      最近更新 更多