函数的定义
首先我们来看一下简单函数定义:
function foo($var){
echo $var;
}
词法分析
在zend/zend_language_scanner.l中我们可以找到如下所示的代码:
<ST_IN_SCRIPTING>"function"{
return T_FUNCTION;
}
语法分析
在zend/zend_language_parse.y文件中找到函数的声明过程标记如下:
function:
T_FUNCTION{$$.u.opline_num = CG(zend_lineno);};
;
is_reference:
/* empty */ {$$.op_type = ZEND_RETURN_VAL;}
| '&' {$$.op_type = ZEND_RETURN_REF;}
;
关注点在function is_reference T_STRING,表示function 关键字,是否引用,函数名。
T_FUNCTION标记只是用来定位函数的声明,表示这是一个函数,而更多的工作是与这个函数相关的东西,包括参数,返回值等。
生成中间代码
语法解析后,我们看到所执行编译函数为zend_do_begin_function_declaration.在zend/zend_complie.c文件中找到其实现如下:
生成的中间代码为ZEND_DECLARE_FUNCTION,根据这个中间代码及操作数对应的op_type。我们可以找到中间代码的执行函数为ZEND_DECLARE_FUNCTION_SPEC_HANDLER
在生成中间代码时,可以看到已经统一了函数名全部为小写,表示函数的名称不是区分大小写的。
执行中间代码
在zend/zend_vm_execute.h文件中找到ZEND_DECLARE_FUNCTION中间代码对应的执行函数:ZEND_DECLARE_FUNCTION_SPEC_HANDLER.此函数只调用了函数do_bind_function。其调用代码为:
do_bind_function(EX(opline),EG(function_table),0);
在这个函数中将EX(opline)所指向的函数添加到EG(function_table)中,并判读是否已经存在相同名称的函数,如果存在则报错。