[李景山php] 深入理解PHP内核[读书笔记]--第四章:函数的实现 --函数的调用和执行

内置函数和用户自定义函数在调用的过程中有什么不一样的呢?


函数的调用


函数被调用需要一些基本的信息,比如函数的名称,参数及函数的定义(也就是函数的具体执行内容),从我们开发者的角度来看,定义了一个函数我们在执行的时候自然知道这个函数叫什么名字,以及调用的时候传递了什么参数,函数的操作内容。但是对于Zend引擎不能想我们这样能“看懂”php源代码,但它需要对代码进行处理以后才能执行。我们还是以下两个小例子开始:

function foo(){
     echo "i'm foo!";
}
foo();

下面我们先看一下其对应的opcodes

[李景山php] 深入理解PHP内核[读书笔记]--第四章:函数的实现 --函数的调用和执行_第1张图片

上面是去除一些细枝末节信息的opcodes,可以看到执行函数部分的opcodes是单独独立出来的,这点对于函数的执行特别重要,现在,我们焦点放到对foo函数的调用上面,调用foo的OPCODE是”DO_FCALL”,DO_FCALL进行函数调用操作时,ZE会在function_table中估计函数名(如前所属,这里的函数名经过str_tolower的处理,所以PHP的函数名d奥写不敏感)查找函数的定义,如果不存在,则报出”Call to undefined function xxx()”的错误信息,如果存在,就返回该函数zend_function结构指针,然后通过function.type的值来判读函数是内部函数还是用户自定义函数,调用zend_execute_internal(zend_internal_function.handler)或者直接调用zend_excute来执行这个函数包括的zend_op_array

函数的执行


内部函数跟外部函数的执行最大的特征就是变量的作用域。在函数执行的时候,进入函数前的环境信息是必须要保存的。在函数执行完毕后,这些环境信息也会被还原,使整个程序继续的执行下去。

内部函数的执行与用户函数不同。用户函数是php语句一条条“翻译”成op_line组成一个op_array,而内部函数则是用C来实现的,因为执行环境也是C环境,所以可以直接调用。

例如如下的例子:

$foo = 'test';
print_r($foo);

[李景山php] 深入理解PHP内核[读书笔记]--第四章:函数的实现 --函数的调用和执行_第2张图片

可以看出,生成的opcodes中,内部函数和用户函数的处理都是由DO_FCALL来进行的。而在其具体实现的zend_do_fcall_common_helper_SPEC()中,则对是否为内部函数进行了判读,如果内部函数,则使用一个比较长的调用

你可能感兴趣的:(php,内核,php,读书笔记,内核)