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                       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来标识变量

文件路径:\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 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 联合体

 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/ 关于作者:专注于微软平台的项目开发。如有问题或建议,请多多赐教! 版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。 特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我 声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是作者坚持原创和持续写作的最大动力!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏debugeeker的专栏

《coredump问题原理探究》Linux x86版3.4节栈布局之函数参数

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xuzhina/article/detai...

331
来自专栏龙渊阁测试精英

Jmeter(五)_函数

1、它有两个参数,第一个参数是要执行的语句,可以是beanshell语句或者是文件地址,是必选参数;第二个参数是保存结果的变量名称,非必选参数。

812
来自专栏炉边夜话

你的变量究竟存储在什么地方?

我相信大家都有过这样的经历,在面试过程中,考官通常会给你一道题目,然后问你某个变量存储在什么地方,在内存中是如何存储的等等一系列问题。不仅仅是在面试中,学校里...

921
来自专栏微信公众号:Java团长

Java开发中对Redis的基本操作总结

想要在 Java 中使用 Redis,我们首先需要安装 redis 服务及 Java redis 驱动。

1254
来自专栏来自地球男人的部落格

Python切片赋值操作

1. 问题 首先来看一小段列表推到的python代码 a = [1,2,3] b = a # 赋值1 b[:] = [x+1 for x in a] print...

1927
来自专栏编程

五撩Python

重复,再重复,你就是专家。 --曾子 1、起手 来说函数。 2、函数 函数就是整理好的一堆可重用的代码,有输入,然后就有输出。 比如我们计算折扣,输入是消费者的...

1596
来自专栏CSDN技术头条

【问底】王帅:深入PHP内核(一)——弱类型变量原理探究

PHP是一门简单而强大的语言,提供了很多Web适用的语言特性,其中就包括了变量弱类型,在弱类型机制下,你能够给一个变量赋任意类型的值。 PHP的执行...

2165
来自专栏大闲人柴毛毛

Java8新特性——StreamAPI(二)

1. 收集器简介 收集器用来将经过筛选、映射的流进行最后的整理,可以使得最后的结果以不同的形式展现。 collect方法即为收集器,它接收Collector接...

2765
来自专栏kalifaの日々

Intel寄存器名称解释及用途,%eax%ebx等都是什么意思

参考资料:https://www.swansontec.com/sregisters.html x86家族的CPU都有8个通用寄存器,每一个寄存器的名字都是一...

5425
来自专栏Lambda

Java8新日期处理API

Java8引入了一套全新的时间日期API,本篇随笔将说明学习java8的这套API。 java.time包中的是类是不可变且线程安全的。新的时间及日期API位...

23610

扫码关注云+社区