This is ugly, but basically works:
<?php declare(ticks=1); function setInterval($callback, $ms, $max = 0) { $last = microtime(true); $seconds = $ms / 1000; register_tick_function(function() use (&$last, $callback, $seconds, $max) { static $busy = false; static $n = 0; if ($busy) return; $busy = true; $now = microtime(true); while ($now - $last > $seconds) { if ($max && $n == $max) break; ++$n; $last += $seconds; $callback(); } $busy = false; }); } function setTimeout($callback, $ms) { setInterval($callback, $ms, 1); }
The interval callback function is called only after a ticking PHP statement. Therefore, if you try to call a function 10 times per second, but you call sleep(10) , you will get 100 executions of your tick function in the packet after the sleep is completed.
Note that there is an additional parameter, setInterval , which limits the number of times it is called. setTimeout simply calls setInterval with a limit of one.
It would be better if unregister_tick_function was called after it expired, but I'm not sure that it would be possible even if there wasn’t a main tick function that controlled and did not register them.
I have not tried to implement anything like this because it is not how PHP is intended to be used. There is probably a much better way to do what you want to do.
Matthew
source share