理解PHP declare()和ticks

时间:2015-07-08 05:19:39

标签: php control-structure

今天我正在浏览php手册并偶然发现了一个控制结构declare

  

declare构造用于设置块的执行指令   代码

这是declare应该做的事情。说实话,我没理解。在再次阅读时,它发现了一个新事物Ticks

  

tick是每N个低级别tickable发生的事件   语句块中解析器执行的语句。价值   对于N,在声明块的指令中使用ticks = N指定   部分。

我也不理解。它是什么意思N low-level tickable statements如果有一个很好的示例代码,那么它很容易理解。但手册中没有找到任何内容。我在SO Q1上发现了一些,这实际上增加了我的好奇心和困惑。那么任何人都可以使用它,我们可以在哪里使用它。

我的实际困惑在于此声明(来自链接的帖子)you can declare a tick-function which checks each n executions of your script whether the connection is still alive or not。因此,当我在php文件上注册tick = 20的tick函数并执行它时,该文件将处于活动状态,直到20执行完成(当它被错误地视为多线程时得到这个想法)。这是我的想法,我不认为它是正确的..

或者它是while($x = 20)

的简单替代品

[编辑1]
我还看到了declare()另一部分php手册Function arguments

的实现

[编辑2]
也在Process Control

  

您可以使用declare()语句指定您的位置   允许回调发生的程序。这允许你   最小化处理异步事件的开销

3 个答案:

答案 0 :(得分:10)

当PHP执行您的脚本时,执行可被视为正在执行的许多语句。大多数语句会导致Tick,但不一定所有语句都会这样做。 (手册说:Typically, condition expressions and argument expressions are not tickable.

当您执行5个语句时,此块通常会导致5个滴答:

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

这个块通常会导致5个滴答,而另一个滴答,因为while循环的结束也被计为一个语句/滴答:

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

declare(ticks=N)register_tick_function()的帮助下,您现在可以在语句/标记之间执行代码。 register_tick_function指定当发生tick事件时应该调用哪个函数。并且声明设置在发生滴答事件之前应该经过多少滴答。

使用declare(ticks=1)register_tick_function('someFunction');,您将在每个语句/勾号之间调用someFunction()代码。

如果您使用declare(ticks=3),那么someFunction()将在每三个语句/ tick上执行。

示例:

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

此脚本将输出:1234x5678x9 就这么简单。

现在链接问题的意思是&#34;连接是否仍然存在&#34;,它本身并不真正有趣,并且实际上并不与上面提到的相关。这只是你可以在每个蜱事件上做的事情。但你也可以做一些完全不同的事情。提到的只是某些脚本可能需要相当长的时间才能执行,而在执行期间,客户端可能会断开连接。 (想象一下,关闭浏览器,同时脚本仍在运行。)默认情况下,PHP将继续运行脚本,即使客户端已断开连接。您可以使用函数connection_aborted()来检测客户端是否已断开连接。这也是你可以在不使用刻度线的情况下做的事情。

现在让我们假设您希望脚本在客户端断开连接后立即停止运行。只需使用......

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

...并且您的脚本将在每次代码声明后调用killme()killme()将检查客户端是否仍然已连接,die()何时无法连接。

答案 1 :(得分:9)

实际上:忽略Wed Jul 08 2015 11:48指令。除非你遇到使用它的代码 - 这是非常罕见的 - 你可以放心地忘记它曾经存在过。

话虽如此,这里是细节。 declare()指令目前用于两个完全不相关的事情:

  • 作为declare(),用于声明PHP文件的编码。 (从这个意义上说,它可以与declare(encoding=…)的服务器端版本相媲美。)

    但不要使用它。在大多数情况下,脚本编码无关紧要。如果它有可能,那么PHP编码应该由<meta charset="…">配置值全局设置(希望为“UTF-8”)。在文件级别设置它是令人困惑和不必要的。

  • 作为zend.script_encoding,用于定义调用tick函数的频率。刻度函数由PHP解释器定期调用,并使用register_tick_function设置。

    虽然php.net上的一些评论建议使用它来实现网络访问的超时,但实际上并没有按预期工作,因为在本机函数调用中阻止解释器时不会触发tick。它可能在基准测试中有一些应用,但除此之外它基本上没用。我会避免它。

答案 2 :(得分:2)

本次未提及的一种用法或可能的重复答案是捕捉信号。

如果您有一个CLI脚本并且想要捕获用户信号(例如SIGHUP或SIGTERM(CTRL + C)),则需要declare(ticks...pcntl_signal https://secure.php.net/manual/en/function.pcntl-signal.php,这样您就可以捕获这些信号(与shell脚本中的陷阱相同)