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.
这是PHP中对 declare 中的 ticks 的定义
中文翻译 Tick(时钟周期)是一个在 declare 代码段中解释器每执行 N 条可计时的低级语句就会发生的事件。N 的值是在 declare 中的 directive 部分用ticks=N
来指定的.
我个人理解的大意就是说, tick 这个周期上会绑定一个事件, 这个事件, 当Zend引擎执行到所设置的 tick (就是N) 行低级语句时, 就执行 register_tick_function() 定义的事件
关于什么是低级语句, http://my.oschina.net/Jacker/blog/32936 这篇文章说的很详细, 有时间的话, 可以研究一下的, 涉及到了PHP的底层 zend 引擎.
declare (ticks = N);
这个东西有什么用?
1. 可以用来调试语句, 根据粗体标明的, 不难看出来, 可以用来调试语句, 可以把执行出错的每一行代码记录下来, 可以看出到底是哪里出错了.
<?php error_reporting(0); declare(ticks = 1); // $result bool function debug () { $debug = debug_backtrace(); if ($debug) { $functionName = $debug['function']; if ( !function_exists($functionName) ) { // file_put_contents('/tmp/declare-debug', 'function is not exists!' . " ", FILE_APPEND); exit("function is not exists! "); } } } register_tick_function('debug'); atest('bb');
2. 可以控制程序执行时间, walkor 大神写过, 拿来用一下. 下面是两个死循环, 但是如下这样写, 程序运行时间不会超过5s .
<?php declare(ticks = 1); $timeStart = time(); function checkTimeout () { global $timeStart; $timeoutSeconds = 5; if (time() - $timeStart > $timeoutSeconds) { exit ('超时' . " "); } } register_tick_function('checkTimeout'); while (1) { $num = 1; } while (1) { $num = 1; }
3. walkor大神 所写的第二个是检测信号的, 拿来用一下.
declare(ticks=1);每执行一次低级语句会检查一次该进程是否有未处理过的信号,测试代码如下:
运行 php signal.php
然后CTL+c 或者 kill -SIGINT PID 会导致运行代码跳出死循环去运行pcntl_signal注册的函数,效果就是脚本exit打印“Get signal SIGINT and exi”退出
declare(ticks=1); pcntl_signal(SIGINT, function(){ exit("Get signal SIGINT and exit "); }); echo "Ctl + c or run cmd : kill -SIGINT " . posix_getpid(). " " ; while(1){ $num = 1; }