PHP 内核之旅系列
PHP内核之旅-1.生命周期
PHP内核之旅-2.SAPI中的Cli
PHP内核之旅-3.变量
一、弱类型语言
php是弱类型语言。一个变量可以表示任意数据类型。
php强大的一部分原因就是因为它是弱类型语言,但是弱类型语言也有它的缺点,使用不当也会造成很大的问题。
定义变量的时候不需要指定变量类型,也不需要初始化变量。
//定义变量$test;
二、PHP的变量类型
php虽然是弱类型语言,但是内部也是有数据类型的,总共有8种
标量类型 | 复合类型 | 特殊类型 |
字符串string | 数组array | 资源resource |
整型integer | 对象object | NULL |
浮点型float(double) | ||
布尔型boolean |
全部类型如下:
1 /* regular data types */ 2 #define IS_UNDEF ??????????????????????0 3 #define IS_NULL ???????????????????????1 4 #define IS_FALSE ??????????????????????2 5 #define IS_TRUE ???????????????????????3 6 #define IS_LONG ???????????????????????4 7 #define IS_DOUBLE ?????????????????????5 8 #define IS_STRING ?????????????????????6 9 #define IS_ARRAY ??????????????????????710 #define IS_OBJECT ?????????????????????811 #define IS_RESOURCE ???????????????????912 #define IS_REFERENCE ??????????????????1013 14 /* constant expressions */15 #define IS_CONSTANT ???????????????????1116 #define IS_CONSTANT_AST ???????????????1217 18 /* fake types */19 #define _IS_BOOL ??????????????????????1320 #define IS_CALLABLE ???????????????????1421 #define IS_ITERABLE ???????????????????1922 #define IS_VOID ???????????????????????1823 24 /* internal types */25 #define IS_INDIRECT ???????????????????1526 #define IS_PTR ????????????????????????1727 #define _IS_ERROR ?????????????????????20
三、内部实现
PHP用结构体_zval_struct来标识变量
文件路径:\Zend\zend_types.h
1 struct _zval_struct { 2 ????zend_value ???????value; ???????????//用来保存具体的变量值 3 ????union { 4 ????????struct { 5 ????????????ZEND_ENDIAN_LOHI_4( //兼容大小字节序,小字节序就是下面的属性,大字节序就是下面四个四个顺序翻转 6 ????????????????zend_uchar ???type, ???????????//变量类型 7 ????????????????zend_uchar ???type_flags, ??//类型掩码,内存管理用到 8 ????????????????zend_uchar ???const_flags, ??9 ????????????????zend_uchar ???reserved) ???????//预留字段,zend执行过程中会用来记录 call info10 ????????} v;11 ????????uint32_t type_info;12 ????} u1;13 ????union { //辅助值14 ????????uint32_t ????next; ????????????????/* hash collision chain */15 ????????uint32_t ????cache_slot; ??????????/* literal cache slot */16 ????????uint32_t ????lineno; ??????????????/* line number (for ast nodes) */17 ????????uint32_t ????num_args; ????????????/* arguments number for EX(This) */18 ????????uint32_t ????fe_pos; ??????????????/* foreach position */19 ????????uint32_t ????fe_iter_idx; ?????????/* foreach iterator index */20 ????????uint32_t ????access_flags; ????????/* class constant access flags */21 ????????uint32_t ????property_guard; ??????/* single property guard */22 ????????uint32_t ????extra; ???????????????/* not further specified */23 ????} u2;24 };
1. value 用来保存具体的变量值,它是一个联合体:zend_value。后面再介绍zend_value结构体。
2. union u1 = 结构体v + type_info
3. 结构体 v: type + type_flags + const_flags + reserved
名称 | 作用 |
type | 标识value类型 |
type_flags | 类型掩码 |
const_flags | |
reserved | 预留字段,zend执行过程中记录call info |
4. type_info: 将v结果的4个成员组合到了一起。
5. union u2 用于一些辅助功能。
zend_value 联合体:
1 typedef union _zend_value { 2 ????zend_long ????????lval; ???????????????//整型变量的值存储在这个变量中 3 ????double ???????????dval; ???????????????//浮点型变量的值存储在这个变量中 4 ????zend_refcounted ?*counted; ???????????//获取不同类型结构的gc头部 5 ????zend_string ?????*str; ???????????????//string字符串存储在这个变量中 6 ????zend_array ??????*arr; ???????????????//数组 7 ????zend_object ?????*obj; ???????????????//对象 8 ????zend_resource ???*res; ???????????????//资源类型 9 ????zend_reference ??*ref; ???????????????//引用类型10 ????zend_ast_ref ????*ast; ???????????????//内核使用的value11 ????zval ????????????*zv; ???????????????//指向另一个zval12 ????void ????????????*ptr; ???????????????//指针,通用类型13 ????zend_class_entry *ce; ???????????????//类14 ????zend_function ???*func; ???????????????//函数15 ????struct {16 ????????uint32_t w1;17 ????????uint32_t w2;18 ????} ww;19 } zend_value;
注意:
1.zend_value 各类型根据字记得类型选择使用不同的成员。
2.zend_value中没有布尔型,布尔型拆分成了IS_TRUE和IS_FALSE两种类型,直接通过结构体v中的变量type区分类型。
PHP内核之旅-3.变量
原文地址:https://www.cnblogs.com/jackson0714/p/php3.html