包括持续时间的循环

时间:2015-09-02 15:03:54

标签: php

我需要创建一个循环,当它超过20秒时结束。 我尝试过以下代码,但它无法运行,永远运行。

修改: 对于简单的代码,它会停止正常,但使用include_once并包括外部文件,即使在20秒过期后仍然保持运行

bot.php

$starttime = time();


while (time() - $starttime < 20) {    

 include_once 'onefile.php';
 include 'somefile.php';
 include 'somefile2.php';

}

编辑2

对于Josh Trii Johnston的回答,如果在X秒内没有结束,过程就会停止。现在的问题是我的案子还有另一个问题。上面提供的样本并不是单独运行的。它也包含在另一个循环文件​​中:

master.php

<?php
       while (1) {   
            include 'bot.php'; 
            sleep(60);
        }

正如你所看到它在一个无限循环上运行而我想要的并不是停止整个循环而只是&#34;打破&#34; bot.php循环,保持主while(1)循环活动。使用提供的解决方案,它将退出所有循环,并终止该过程。

2 个答案:

答案 0 :(得分:7)

PHP不是魔术,不能像那样停止执行脚本。只有在while内的所有处理完成后,才会检查include条件。

您可以尝试拨打register_tick_function()并提供可以检查已用时间的回调,并在需要时提供exit

现在有更多示例!

<?php
declare(ticks=1);

define('START_TIME', time());

// lambda uses START_TIME constant
register_tick_function(function() {
    if (time() - START_TIME > 20) {
        echo 'Script execution halted. Took more than 20 seconds to execute';
        exit(1);
    }
}, true);

include_once 'onefile.php';
include 'somefile.php';
include 'somefile2.php';
?>

这将停止在20秒标记后发生的下一个tick,而不是20秒。

根据您当前的更新编辑#2工作代码

此代码的工作原理类似,但不是暂停脚本执行,而是抛出TimeLimitException,然后使用goto跳转到执行点。这很黑,但它可以满足你的需要。

<?php
declare(ticks=1);

$start_time = time();
class TimeLimitException extends Exception {}

// lambda uses $start_time global so it can reset
// the timer after the time limit is reached
register_tick_function(function() {
    global $start_time;
    if (time() - $start_time > 20) {
        echo 'Script execution halted. Took more than 20 seconds to execute', PHP_EOL;
        $start_time = time();
        throw new TimeLimitException();
    }
}, true);

try {
    // time limit will reset to here. Cannot jump to a label in a loop
    limit:

    while (1) {
        sleep(1);
        echo 'outer ';
        while (1) {
            echo 'inner ';
            sleep(2);
        }
    }
} catch (TimeLimitException $e) {
    echo 'time limit hit, jumping to label `limit`', PHP_EOL;
    goto limit;
}

答案 1 :(得分:1)

实际上,像set_time_limit之类的东西是更好的方法。

或者,如果您只想限制包含时间,请执行主题。

class workerThread extends Thread {
    public function __construct(){
        $this->starttime=time();
    }

    public function run(){
        include_once 'onefile.php';
        include 'somefile.php';
        include 'somefile2.php';
        $this->done=true;
    }
    public function finished(){
        return $this->done || (time() - $this->starttime < 20)
    }
}
$worker=new workerThread();
$worker->start();
while(!$worker->finished()){}