Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding PHP declare() and ticks

People also ask

What is PHP declare?

The declare keyword sets an execution directive for a block of code. If the declare statement is not followed by a block then the directive applies to the rest of the code in the file.

What are ticks in PHP?

Put simply, a tick is a special event that occurs internally in PHP each time it has executed a certain number of statements. These statements are internal to PHP and loosely correspond to the statements in your script.

What is tick function?

The tick function is unlike other lifecycle functions in that you can call it any time, not just when the component first initialises. It returns a promise that resolves as soon as any pending state changes have been applied to the DOM (or immediately, if there are no pending state changes).


When PHP is executing your script, the execution can be seen as a lot of statements being executed. Most statements cause a Tick, though not necessarily all statements do so. (Manual says: Typically, condition expressions and argument expressions are not tickable.)

This block would normally cause 5 ticks, as you are executing 5 statements:

$a = 1;
$B = 2;
$a = 3;
$B = 4;
$a = 5;

And this block would normally cause 5 ticks, and one more tick as the end of the while loop also is counted as a statement/tick:

while ($i < 5)
    $a++;

With the help of declare(ticks=N) and register_tick_function(), you can now execute code in between the statements/ticks. The register_tick_function specifies which function should be called when a tick event occurs. And the declare sets how many tick should pass, before a tick event occurs.

With declare(ticks=1) and register_tick_function('someFunction'); you will call someFunction() code in between every statement/tick.

If you use declare(ticks=3), then someFunction() will be executed on every third statement/tick.

Example:

function handler(){
    echo "x";
}
register_tick_function("handler");
$i = 0;
declare(ticks = 4) {
    while ($i < 9)
        echo ++$i;
}

This script will output: 1234x5678x9 It's that simple.

Now what is meant in the linked question with "whether the connection is still alive", is not really interesting on itself and is not actually related to the above mentioned. It is just something you COULD do on every tick event. But you can also do something totally different. What is mentioned is simply that some scripts can take quite some time to execute and that during the execution, the client can disconnect. (Imagine closing the browser, while the script is still running.) PHP will by default continue to run the script, even if the client has disconnected. You can use the function connection_aborted() to detect if the client has disconnected. This is something you COULD also do without using ticks at all.

Now let's say for example that you want your script to stop running as soon as the client disconnects. Simply use ...

function killme() {
    if (connection_aborted()) {
        die();
    }
}
register_tick_function('killme');
declare(ticks=1);

... and your script will call killme() after each statement of your code. killme() will check if the client is still connected and die() when it isn't.


In practice: Ignore the declare() directive. Unless you run into code that makes use of it — which is very rare — you can safely forget that it ever existed.

That being said, here's the details. The declare() directive is currently used for two completely unrelated things:

  • As declare(encoding=…), for declaring the encoding of a PHP file. (In this sense, it's comparable to a server-side version of <meta charset="…">.)

    But don't use this. Under most circumstances, the script encoding doesn't matter. If by some chance it does, the PHP encoding should be set globally (hopefully to "UTF-8") by the zend.script_encoding configuration value. Setting it at the file level is confusing and unnecessary.

  • As declare(ticks=…), for defining the frequency at which tick functions are called. Tick functions are called periodically by the PHP interpreter, and are set up using register_tick_function.

    While some of the comments on php.net suggest using it to implement timeouts on network accesses, that doesn't actually work as expected, as ticks are not fired while the interpreter is blocked in a native function call. It might have some applications in benchmarking, but outside of that it's basically useless. I'd avoid it.


The one usage not mentioned in this or the possible duplicate answer is catching signals.

If you have a CLI script and want to catch user signals (like SIGHUP or SIGTERM (CTRL+C)), you need declare(ticks... together with pcntl_signal https://secure.php.net/manual/en/function.pcntl-signal.php which allows you to catch those signals (same like trap in shell scripts)