• PHP内核之旅-3.变量


    PHP 内核之旅系列

    一、弱类型语言

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

    文件路径:endzend_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

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

  • 相关阅读:
    CF1394A Boboniu Chats with Du 题解
    P3377 【模板】左偏树(可并堆)题解
    P2152 [SDOI2009]SuperGCD 题解
    在其他模块中调用代码
    教程:创建Go模块
    Go入门
    反悔贪心
    codeforces 1569 E. Playoff Restoration (meet-in-the-middle)
    codeforces 1036 F. Relatively Prime Powers (容斥+精度处理+大数边界处理)
    icpc沈阳2020 H. The Boomsday Project (dp+二分)
  • 原文地址:https://www.cnblogs.com/jackson0714/p/php3.html
Copyright © 2020-2023  润新知