I need to create a cycle to end when it is longer than 20 seconds. I have tried the following code but it's not working, running forever.
EDIT: For simple code it will stop fine, but using the include_once and include the external files keep running even after the 20 seconds expire
bot.php
$starttime = time();
while (time() - $starttime < 20) {
include_once 'onefile.php';
include 'somefile.php';
include 'somefile2.php';
}
EDIT 2:
With Josh Trii Johnston's answer the proccess is really stopped if not concluded within X seconds. The problem now is that there is another requisit on my case.. The sample provided above does not run alone. It is also included on another loop file like this:
master.php
<?php
while (1) {
include 'bot.php';
sleep(60);
}
As you can see it is running on a infinite loop and what I want is not stop the entire loop but only "break" the bot.php loop, keeping the main while(1) loop active. With the provided solution it exits all the loops and the process is terminated.
PHP is not magic and cannot stop execution mid-script like that. The while
condition is only checked once all processing inside your include
s are completed.
You can try calling register_tick_function()
and provide a callback that can check the time elapsed and exit
if needed.
Now with more example!
<?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';
?>
This will halt on the next tick
that happens after the 20 second mark, not exactly 20 seconds.
Edit #2 Working code based on your current updates
This code works on a similar principle but instead of halting script execution, it throws a TimeLimitException
which is then used to jump to a point of execution using goto
. It is hacky, but it accomplishes what you need.
<?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;
}
Actually, something like set_time_limit is a better approach.
Alternatively, if you just want to limit the includetime, do Threads.
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()){}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With