一、弱类型语言
php是弱类型语言。一个变量可以表示任意数据类型。
php强大的一部分原因就是因为它是弱类型语言,但是弱类型语言也有它的缺点,使用不当也会造成很大的问题。
定义变量的时候不需要指定变量类型,也不需要初始化变量。
代码语言:javascript复制//定义变量
$test;
二、PHP的变量类型
php虽然是弱类型语言,但是内部也是有数据类型的,总共有8种
标量类型 | 复合类型 | 特殊类型 |
---|---|---|
字符串string | 数组array | 资源resource |
整型integer | 对象object | NULL |
浮点型float(double) | ||
布尔型boolean |
全部类型如下:
代码语言:javascript复制 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 7
10 #define IS_OBJECT 8
11 #define IS_RESOURCE 9
12 #define IS_REFERENCE 10
13
14 /* constant expressions */
15 #define IS_CONSTANT 11
16 #define IS_CONSTANT_AST 12
17
18 /* fake types */
19 #define _IS_BOOL 13
20 #define IS_CALLABLE 14
21 #define IS_ITERABLE 19
22 #define IS_VOID 18
23
24 /* internal types */
25 #define IS_INDIRECT 15
26 #define IS_PTR 17
27 #define _IS_ERROR 20
三、内部实现
PHP用结构体_zval_struct来标识变量
文件路径:Zendzend_types.h
代码语言:javascript复制 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 info
10 } 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 联合体:
代码语言:javascript复制 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; //内核使用的value
11 zval *zv; //指向另一个zval
12 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区分类型。
参考资料:
http://www.php-internals.com/
《PHP7内核剖析》
作 者: Jackson0714 出 处:http://www.cnblogs.com/jackson0714/ 关于作者:专注于微软平台的项目开发。如有问题或建议,请多多赐教! 版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。 特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我 声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是作者坚持原创和持续写作的最大动力!