执行php代码-PHP底层实现

php底层

PHP是弱语言类型,但是底层是如何实现的呢? 本文将简单讲一下PHP的底层实现。 首先我们来说说PHP代码的执行过程。

PHP代码的执行过程:

编译语言:

对于C语言、C++,将其编译成机器码(二进制)来运行。

在java语言中,.java被编译成.class,称为字节码,由jvm运行。

翻译语言:

解释器解释并执行。 一个典型的例子是linux shell。

解释器逐行执行命令。

PHP 有点特殊。 虽然是脚本语言,但并不是用套路来解释的。

相反,zend 虚拟机掩盖了操作系统之间的差异。

PHP代码被编译成opcode,opcode由zend虚拟机执行。

但是--opcode,一旦PHP脚本结束,opcode就被消除了。

思考:操作码可以缓存吗?

PHP本身不支持,但是apc、xcache等加速器可以实现这种效果。

代码执行函数_代码执行顺序_执行php代码

php底层

PHP底层是用C语言实现的。 C语言是强类型语言,而PHP是弱类型语言。

它是如何实现的?

PHP变量的底层实现:

我们解压PHP源码包,看到如下目录

PHP 源代码

在,

核心---Zend目录执行php代码,这是zend的虚拟实现。 包括栈、数据类型、编译器等等,都是在这里实现的。

最重要的main——PHP的一些内置函数,最重要的函数都放在这里。

最大的目录ext——PHP扩展。

PHP的大部分功能都是通过扩展方式实现的。

如果您开发扩展,也将其放在 ext 目录中。

Zend 的变量表示:

答:Zend实现了zval结构

value: [Union],union的内容可能是C语言中的long、double、hashtable...

type:变量类型,IS_NULL、IS_BOOL、IS_STRING...IS_RESOURCE

引用计数_GC

is_ref_gc

喜欢:

$a = 3;

值:[长lval = 3]

类型:IS_LONG

$a = 3.5

值:[双 dval = 3.5]

类型:IS_DOUBLE

PHP解析

怀疑:

PHP中有8种数据类型,为什么zval->value联合中只有5种?

回答:

1:NULL,只需zval->type = IS_NULL即可表示,无需设置value的值。

2:BOOL类型,zval->type = IS_BOOL,则设置zval.value.lval = 1/0;

3:资源类型,资源类型往往是服务器上打开的socket,比如读文件的socket。

zval->type = IS_RESOURCE, zval->tyoe.lval = 服务器上打开的套接字号

发现:

在PHP中执行php代码,字符串类型和长度已经被缓存了。 当调用strlen时,系统可以直接返回其厚度,无需估计。

符号表---变量名册

多变的

变量的形状参与引用

注意:

当传递值形式参数时,

取:$a = 3; 以$b = $a为例,结构体没有再次形成,而是两个变量共享一个结构体。

此时两个变量指向同一个结构体,refcount_gc值为2

示例

思考:a和b指向同一个结构体,那么如果修改a或b,对方会受到影响吗?

答案:不,

因为两者,如果其中之一发生变化,就会导致结构分裂。

该结构一开始是共享的,当一方想要更改值时,该结构就会被拆分。

这个功能叫做cow,copy on write,

如下所示:

变量解析

引用形参时,双方共享一个结构体(is_ref_gc=1)

发生的变化如下图所示

分配时

引用时的一些奇怪现象

执行php代码_代码执行顺序_代码执行函数

函数执行期间堆栈发生变化

当函数被调用时,会为这个函数生成一个“执行环境变量”结构体,里面存储了当前函数的名称、参数、对应的类……等等。

名为_zend_execute_data{}结构

这个结构中有两个重要的信息:

*op_array------>是函数的执行步骤

*hash_table---->symbol_table 该函数对应的符号表

想一想:1个函数递归调用自身3次,比如t

在堆栈上,必须有3个execute_data生成。 然而这3个execute_data--->对应了几个*op_array;

答:函数编译后,会生成一个*op_array,因为函数的执行逻辑是固定的。

再问:生成了多少个symbol_table?

答:生成3个符号表。

函数中的静态变量是如何生成的?

t() {

} 自己调用了3次

[t_3执行_数据] ---->[符号_表_3]

[t_2执行数据] ---->[符号表_2]

[t_1执行数据] ---->[符号表_1]

*op_array->*静态变量表