PHP 内核之旅系列

一、弱类型语言

php是弱类型语言。一个变量可以表示任意数据类型。

php强大的一部分原因就是因为它是弱类型语言,但是弱类型语言也有它的缺点,使用不当也会造成很大的问题。

定义变量的时候不需要指定变量类型,也不需要初始化变量。

//定义变量
$test;

二、PHP的变量类型

php虽然是弱类型语言,但是内部也是有数据类型的,总共有8种

标量类型 复合类型 特殊类型
字符串string 数组array 资源resource
整型integer 对象object NULL
浮点型float(double)    
布尔型boolean    

全部类型如下:

 /* regular data types */
#define IS_UNDEF 0
#define IS_NULL 1
#define IS_FALSE 2
#define IS_TRUE 3
#define IS_LONG 4
#define IS_DOUBLE 5
#define IS_STRING 6
#define IS_ARRAY 7
#define IS_OBJECT 8
#define IS_RESOURCE 9
#define IS_REFERENCE 10 /* constant expressions */
#define IS_CONSTANT 11
#define IS_CONSTANT_AST 12 /* fake types */
#define _IS_BOOL 13
#define IS_CALLABLE 14
#define IS_ITERABLE 19
#define IS_VOID 18 /* internal types */
#define IS_INDIRECT 15
#define IS_PTR 17
#define _IS_ERROR 20

三、内部实现

PHP用结构体_zval_struct来标识变量

文件路径:\Zend\zend_types.h

 struct _zval_struct {
zend_value value; //用来保存具体的变量值
union {
struct {
ZEND_ENDIAN_LOHI_4( //兼容大小字节序,小字节序就是下面的属性,大字节序就是下面四个四个顺序翻转
zend_uchar type, //变量类型
zend_uchar type_flags, //类型掩码,内存管理用到
zend_uchar const_flags,
zend_uchar reserved) //预留字段,zend执行过程中会用来记录 call info
} v;
uint32_t type_info;
} u1;
union { //辅助值
uint32_t next; /* hash collision chain */
uint32_t cache_slot; /* literal cache slot */
uint32_t lineno; /* line number (for ast nodes) */
uint32_t num_args; /* arguments number for EX(This) */
uint32_t fe_pos; /* foreach position */
uint32_t fe_iter_idx; /* foreach iterator index */
uint32_t access_flags; /* class constant access flags */
uint32_t property_guard; /* single property guard */
uint32_t extra; /* not further specified */
} u2;
};

1. value 用来保存具体的变量值,它是一个联合体:zend_value。后面再介绍zend_value结构体。

2. union u1 = 结构体v + type_info

3. 结构体 v: type + type_flags + const_flags + reserved

结构体v
名称 作用
type 标识value类型
type_flags 类型掩码
const_flags  
reserved  预留字段,zend执行过程中记录call info

4. type_info: 将v结果的4个成员组合到了一起。

5. union u2 用于一些辅助功能。

zend_value 联合体

 typedef union _zend_value {
zend_long lval; //整型变量的值存储在这个变量中
double dval; //浮点型变量的值存储在这个变量中
zend_refcounted *counted; //获取不同类型结构的gc头部
zend_string *str; //string字符串存储在这个变量中
zend_array *arr; //数组
zend_object *obj; //对象
zend_resource *res; //资源类型
zend_reference *ref; //引用类型
zend_ast_ref *ast; //内核使用的value
zval *zv; //指向另一个zval
void *ptr; //指针,通用类型
zend_class_entry *ce; //类
zend_function *func; //函数
struct {
uint32_t w1;
uint32_t w2;
} ww;
} 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/

关于作者:专注于微软平台的项目开发。如有问题或建议,请多多赐教!

版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信

声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是作者坚持原创和持续写作的最大动力!

PHP内核之旅-3.变量的更多相关文章

  1. PHP内核之旅-2.SAPI中的Cli

    PHP 内核之旅系列 PHP内核之旅-1.生命周期 PHP内核之旅-2.SAPI中的Cli 一.SAPI是什么? 1.1 理解SAPI (1)SAPI是PHP框架的接口层.有很多种服务器的SAPI的实 ...

  2. PHP内核之旅-6.垃圾回收机制

    回收PHP 内核之旅系列 PHP内核之旅-1.生命周期 PHP内核之旅-2.SAPI中的Cli PHP内核之旅-3.变量 PHP内核之旅-4.字符串 PHP内核之旅-5.强大的数组 PHP内核之旅-6 ...

  3. PHP内核之旅-5.强大的数组

    PHP 内核之旅系列 PHP内核之旅-1.生命周期 PHP内核之旅-2.SAPI中的Cli PHP内核之旅-3.变量 PHP内核之旅-4.字符串 PHP内核之旅-5.强大的数组 PHP内核之旅-6.垃 ...

  4. PHP内核之旅-4.可变长度的字符串

    PHP 内核之旅系列 PHP内核之旅-1.生命周期 PHP内核之旅-2.SAPI中的Cli PHP内核之旅-3.变量 PHP内核之旅-4.字符串 PHP内核之旅-5.强大的数组 PHP内核之旅-6.垃 ...

  5. MOOC Linux内核之旅小结【转】

    转自:https://blog.csdn.net/titer1/article/details/45345123 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csd ...

  6. Linux内核之旅

    http://www.kerneltravel.net/ Linux内核之旅 Linux Kernel Travel

  7. Linux内核同步:per_cpu变量

    per cpu变量相关函数和宏 DEFINE_PER_CPU_SHARED_ALIGNED(type,name):静态分配per_cpu数组,数组名为name,结构类型为type DEFINE_PER ...

  8. PHP内核之旅-1.生命周期

    1.SAPI接口 PHP具体应用的编程接口. 2.开始和结束 PHP开始执行以后会经过两个主要的阶段: 处理请求之前的开始阶段和请求之后的结束阶段. 1.1开始阶段: 1.1.1 模块初始化阶段(MI ...

  9. 陈莉君教授: 回望踏入Linux内核之旅

    本文系转载,著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 作者: 陈莉君 来源: 微信公众号linux阅码场(id: linuxdev) 初次踏入Linux 几多耕耘,几多收获 ...

随机推荐

  1. Leetcode_75_Sort Colors

    本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/43302343 Given an array with n  ...

  2. 【Android 应用开发】Android中使用ViewPager制作广告栏效果 - 解决ViewPager占满全屏页面适配问题

    . 参考界面 : 携程app首页的广告栏, 使用ViewPager实现        自制页面效果图 : 源码下载地址: http://download.csdn.net/detail/han1202 ...

  3. SpriteBuilder中如何固定两个互不接触的物理物体?

    如下图: 这个弹簧装置由3部分组成(从上到下): 弹板 弹簧 弹簧金属底座 其中弹板将固定在弹簧上(但并没有接触,如上图),这就引出一个有趣的问题:怎么样才能将两个独立的物理物体(注意:是物理物体)固 ...

  4. Gradle 1.12用户指南翻译——第四十章. ANTLR 插件

    本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...

  5. myBatis源码学习之SqlSessionFactory

    上一篇博客 SqlSessionFactoryBuilder 中介绍了它的作用就是获得DefaultSqlSessionFactory SqlSessionFactory是一个接口,其具体实现类是De ...

  6. Android开源经典项目

    目前包括: Android开源项目第一篇--个性化控件(View)篇   包括ListView.ActionBar.Menu.ViewPager.Gallery.GridView.ImageView. ...

  7. HBase BlockCache

    1. Cache 读写  调用逻辑:  hmaster.handleCreateTable->HRegion.createHRegion-> HRegion. initialize-> ...

  8. HBase中创建索引

    hbasene(https://github.com/akkumar/hbasene)是开源项目,在hbase存储上封装使用Lucene来创建索引,代码API非常简单,熟悉lucene的朋友可以很方便 ...

  9. 坚持自己的追求,迎来 “中国系统开发网” (CSDN)的专访

    坚持自己的追求,迎来 "中国系统开发网" (CSDN)的专访: 专访马根峰:海量数据处理与分析大师的中国本土程序员" http://www.csdn.net/articl ...

  10. ZYThumbnailTableView类似于小型阅读器

    Demo github地址: https://github.com/liuzhiyi1992/ZYThumbnailTableView  原文地址:http://zyden.vicp.cc/zythu ...