Reputation: 4615
Today I was looking through the php manual and stumbled upon a control structure declare.
The declare construct is used to set execution directives for a block of code
This is what declare
is supposed to do. To be honest I didn't understood it. On reading again it found a new thing Ticks
A tick is an event that occurs for every N low-level tickable statements executed by the parser within the declare block. The value for N is specified using ticks=N within the declare block's directive section.
I didn't understand it either. what does it mean by N low-level tickable statements
If there had been a good sample code, then it would have been easy to understand. But none was found in the manual. I have found some on SO Q1, which actually increased my curiosity and confusion. So can anyone what is this for and where can we use this.
My actual confusion is with this statement (from the linked so post) you can declare a tick-function which checks each n executions of your script whether the connection is still alive or not
. So when I register a tick function with tick = 20 on a php file and execute it, the file will be alive till 20 execution is complete(got this idea when it was wrongly considered as multithreaded). This is the idea i have got, I dont think its correct..
Or is it a simple replacement for while($x = 20)
[EDIT 1]
I have also seen the implementation of declare()
another section of php manual Function arguments
[EDIT 2]
Also in Process Control
You use the declare() statement to specify the locations in your program where callbacks are allowed to occur. This allows you to minimize the overhead of handling asynchronous events
Upvotes: 33
Views: 8198
Reputation: 13047
On newer versions of PHP, in most cases declare(ticks=1);
can be replaced by:
pcntl_async_signals(true);
Upvotes: 0
Reputation: 11832
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.
Upvotes: 34
Reputation: 3162
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)
Upvotes: 4
Reputation:
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.
Upvotes: 10