php底层

php是一种弱措辞类型,但是他底层究竟是怎么实现的呢?本文就大略讲讲php的底层的实现方法,首先呢,我们先讲讲php代码的实行过程。

PHP代码的实行过程:

编译型措辞:

php底层实现PHP的底层实现 Java

对付C措辞,C++, 编译成机器码(二进制)来运行.

java措辞, 把.java编译成 .class,称为bytecode, 由jvm来运行.

阐明措辞:

阐明器阐明实行. 范例的如 linux shell.

阐明器逐行来实行命令.

PHP稍有分外之处,虽然是一个脚本措辞,但不是靠阐明器阐明.

而是 zend 虚拟机,屏蔽了操作系统的差异.

php代码编译成opcode, 由zend虚拟机来实行opcode.

但是---opcode, PHP脚本一结束,opcode就打消了.

思考:opcode能否缓存?

PHP本身不支持,但是apc,xcache等加速器,实现了这样的效果.

php的底层

PHP底层用C措辞来实现的,C措辞是强类型,而PHP是弱类型措辞.

是如何实现的呢?

PHP变量的底层实现:

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

php源码

个中,

最核心的---Zend目录, 这是zend虚拟的实现. 包括栈,数据类型,编译器等,都在这实现.

最紧张的main --PHP的一些内建函数,最紧张函数都在这里放着.

最大的一个目录 ext -- PHP的扩展.

PHP的大部分功能,都因此extenstion形式来完成的.

如果你开拓了一个扩展,也放在ext目录下.

Zend对变量的表示:

答: zend实现了 zval构造体

{

value: [联合体] ,联合体的内容可能是C措辞中的long,double,hashtable...

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

refcount_gc

is_ref_gc

}

如:

$a = 3;

{

value : [long lval = 3]

type: IS_LONG

}

$a = 3.5

{

value: [double dval = 3.5]

type: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: Resourc型 ,资源型 每每是做事器上打开的一个接口,如果 文件读取接口.

zval->type = IS_RESOURCE, zval->tyoe.lval = 做事器上打开的接口的编号

创造:

PHP中,字符串类型,长度是已经缓存的,调用strlen时,系统可以直接返回其长度,不必打算.

符号表 --- 变量的花名册

变量

变量的赋值与引用

把稳:

在传值赋值时,

以: $a = 3 ; $b = $a为例, 并没有再次产生构造体,而是2个变量共用1个构造体.

此时,2个变量,指向同1个构造体, refcount_gc 值为2

php示例

思考: a, b指向同一个构造体, 那么,修正a,或b ,对方会不会受滋扰?

答: 不会,

由于2者,有一方修正时,将会造成构造体的分裂.

构造体一开始共用, 到某一方要修正值时,才分裂.

这种特点,称为cow , copy on write ,

如下图:

变量解析

当引用赋值时, 双方共用一个构造体(is_ref_gc=1)

发生如下图的变革

赋值时

引用时的一些怪征象

函数实行时的栈变革

当函数调用时,为此函数天生了一个”实行环境变量”的构造体,里面存储了当前函数的名称,参数,对应的类....等等信息.

称为_zend_execute_data {}构造体

这个构造体中,还有2个主要的信息:

{

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 execute_data] ---->[symbol_table_3]

[t_2 execute_data] ---->[symbol_table_2]

[t_1 execute_data] ---->[symbol_table_1]

|

|

|

op_array->静态变量表