PHP的执行是通过Zend engine(ZE, Zend引擎), ZE是用C编写
PHP的常见变量类型: int/float/long int /bool string array object resourse
———————————————————————————————————————
PHP变量:
变量实现结构:
在PHP内核中,所有的变量都是用一个C语言结构-zval来保存的, 在Zend/zend.h中我们可以看到zval的定义:
typedef struct _zval_struct {
zvalue_value value; //存放值,有多种类型的存放方式是一个联合体,根据type字段来储存一个变量的真正类型
zend_uint refcount;/*引用计数*/
zend_uchar type;//根据类型来决定获取value的方式
zend_uchar is_ref; /*变量是否引用*/
} zval;
变量作用域:
在PHP中,所有的变量都会存储在一个数组中(确切的说是hash table), 并且,PHP也是通过不同的数组来实现变量的作用域的。
当你创建一个变量的时候,PHP会为这个变量分配一个zval,填入相应的变量值,然后将这个变量的名字,和指向这个zval的指针填入一个数组中。然后,当你获取这个变量的时候,PHP会通过查找这个数组,获得对应的zval。
这些数组,又分全局符合表和活动符号表:
比较特殊的,就是函数的参数$para了,是保存在的活动符号表的,但是与他对应的zval指针,会指向一个保存一份全局变量的copy的zval, 及全局中zval引用+1,具体涉及的就是PHP变量copy and write机制。
copy and write机制:
当使用变量复制的时候 ,PHP内部并不是真正的复制,而是采用指向相同的结构来尽量节约开销,同时引用+1。
$i = 4; //内核创建一个zval指针,并且为其以堆的方式开辟空间,让指针指向这个空间,将zval中的成员引用计数置为1,类型标记为整形,并且申请一个zvalue_value指针,同样以堆的方式以其开辟空间,同时将该联合体中的lval赋值为4,并且在symbal_table的hash表中记录变量i和zval指针的映射关系
$j = $i; //没有在申请内存空间,在zval的成员中引用计数标记为2
$j = 5; //内核重新创建zval指针,重复第一步的步骤,我就不重复说明了,重点是将旧的zval引用计数标记为1
总结:
1.所有的php变量开辟的内存空间都是在堆中,无论是临时变量还是全局变量,只是php的临时变量记录在active_symbal_table表中,全局变量记录中symbal_table表中
2.php干嘛比C慢。多做了这么多事,能不慢吗?
3.当php类似$j = $i这种变量赋值时,是没有内存开销的,也就是你赋值个几万个,也只是引用计数变成几万而己,这个和C语言是不一样的。而当变量的值发生变化时,才会进行重新开辟内存空间,这个机制我们称为copy and write机制
———————————————————————————————————————
PHP代码的解释过程:
PHP的语言引擎Zend Engine(ZE)解释PHP代码分四个步骤:
1.Scanning(Lexing) ,将PHP代码,去掉空格 ,注释,分割成一个一个的token。
2.Parsing, ,将Tokens转换成简单而有意义的表达式
3.Compilation, 给语法分析器将表达式编译成Opocdes, Opcode是一种PHP脚本编译后的中间语言
4.Execution, 顺次执行Opcodes,每次一条,从而实现PHP脚本的功能。
网友评论