欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

php控制结构语句declare中tick的用法详解

程序员文章站 2022-03-17 22:57:48
...
declare 结构用来设定一段代码的执行指令。declare 的语法和其它流程控制结构相似:

directive 部分允许设定 declare 代码段的行为。目前只认识两个指令:ticks(更多信息见下面 ticks 指令)以及encoding(更多信息见下面 encoding指令)。

Note:

ticks 指令在 PHP 5.3.0 中是过时指令,将会从 php 6.0.0 移除。

encoding 是 PHP 5.3.0 新增指令。

Tick 是一个在 declare 代码段中解释器每执行 N 条低级语句就会发生的事件。N 的值是在 declare 中的 directive部分用 ticks=N 来指定的。

在每个 tick 中出现的事件是由 register_tick_function() 来指定的。更多细节见下面的例子。注意每个 tick 中可以出现多个事件。

看完手册还是觉得云里雾里,再看看别人是怎么描述:

根据代码解析:

<?php    
    function doTicks ()    
    {    
        echo 'Ticks';    
    }    
    register_tick_function('doTicks');    
    declare(ticks = 1) {    
        for ($x = 1; $x < 10; ++ $x) {    
            echo $x * $x . '<br />';    
        }    
    }    
 ?>

运算结果:

1    
TicksTicks4    
TicksTicks9    
TicksTicks16    
TicksTicks25    
TicksTicks36    
TicksTicks49    
TicksTicks64    
TicksTicks81    
TicksTicksTicksTicks

产生三个疑问:

(1)为什么先输出1之后才输出“Ticks”?

(2)为什么在输出81后还输出四个Ticks ?

(3)declare中的for循环怎么分解成低级语句(low-level)?

这是每个初次接触ticks的人都会碰到的问题。首先register_tick_function函数定义了每个tick事件发生时的处理函数。那么什么是tick事件呢?

有三层意思:

(1) tick是一个事件。

(2) tick事件在PHP每执行N条低级语句就发生一次,N由declare语句指定。

(3)可以用register_tick_function()来指定tick事件发生时应该执行的操作。

很明显,理解上面的输出结果最关键的是了解什么是低级语句(low-level statements),它又是如何进行计数的。我们首先还是将上面的程序通过OPDUMP编译成OPCODEs:

很明显,PHP的编译过程已经在编译后每条语句的OPCODE序列中插入了TICKS指令用于处理tick事件。那么这些TICKS是根据什么规则来插入的呢?

我们还是从PHP Zend Engine的源代码中寻找答案。

通过简单的文本搜索我们可以知道生成ZEND_TICKS指令的唯一函数是zend_do_ticks(该函数的实现在zend_compile.c中)。

现在再从PHP的语法分析文件zend_language_parser.y(PHP使用bison来做语法分析,所有的语法规则均定义在zend_language_parser.y中)中寻找调用zend_do_ticks的地方。

再一次使用简单的文本搜索,我们可以得到调用zend_do_ticks的三条语法规则:

statement:    
unticked_statement { zend_do_ticks(TSRMLS_C); }    
 | ...    
 ;    
function_declaration_statement:    
unticked_function_declaration_statement { zend_do_ticks(TSRMLS_C); }    
 ;    
class_declaration_statement:    
unticked_class_declaration_statement { zend_do_ticks(TSRMLS_C); }    
 ;

也就是说,PHP编译会在statement(语句), function_declaration_statement(函数定义语句), class_declaration_statement后插入TICKS处理函数,即它会在每条statement,函数声明,类(实际上还包括接口)声明后插入一条TICKS指令。

函数与类声明语句比较好理解,根据unticked_function_declaration_statement的语法定义:

unticked_function_declaration_statement:    
function is_reference T_STRING { zend_do_begin_function_declaration(&$1, &$3, 0, $2.op_type, NULL TSRMLS_CC); }    
 '(' parameter_list ')' '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1TSRMLS_CC); }    
;

可以知道function_declaration_statement是完整的函数声明,也就是说,一个函数的定义包括完整的函数原形及函数体算一条function_declaration_statement。

以上就是php控制结构语句declare中tick的用法详解的详细内容,更多请关注其它相关文章!