PHP7的基本变量有哪些,用法是怎样的
Admin 2022-07-30 群英技术资讯 259 次浏览
我们都知道PHP的变量是弱类型的,声明的时候无需指定类型。那么这里面具体是怎么实现的呢?这就得从变量的基础结构说起了。
在源码文件 zend_type.h 中,可以看到 zval 的定义:
typedef struct _zval_struct zval; struct _zval_struct { zend_value value; /* value */ union { struct { ZEND_ENDIAN_LOHI_4( zend_uchar type, /* active type */ zend_uchar type_flags, zend_uchar const_flags, zend_uchar reserved) /* call info for EX(This) */ } 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; }
zval 的结构由一个保存变量类型的值或指针的 union 联合体 zend_value 以及两个 union 联合体 u1 和 u2 组成
u1的作用是用来保存变量类型及其信息,其里面的字段用处如下:
type:记录变量类型。 即可通过 u2.v.type 来访问到
type_flags:对应变量特有类型的标记(如常量类型,需引用计数类型,不可变类型),不同类型的变量对应的 flag 不一样。
const_flags:常量类型的标记
reserved:保留字段
u2 主要是辅助作用,由于结构体的内存对齐,所以 u2 的的这块空间有或者没有 u2 都是已经占据空间了,所以就利用起来。u2的辅助字段里面记录了很多类型信息,这些信息对内部功能有很大的好处,或提升缓存友好性或减少了内存寻址的操作。这里介绍其中部分字段。
next:用来解决哈希冲突问题(哈希冲突这个目前还不懂),记录冲突的下一个元素位置。
cache_slot:运行时缓存。在执行函数时会优先去缓存中查找,若缓存中没有,再去全局的 function 表中查找。
num_args:函数调用时传入参数的个数
access_flags:对象类的访问标识,如public protected private 这些。
typedef union _zend_value { zend_long lval; /* 整型*/ double dval; /* 浮点型 */ zend_refcounted *counted; zend_string *str; zend_array *arr; zend_object *obj; zend_resource *res; zend_reference *ref; zend_ast_ref *ast; zval *zv; void *ptr; zend_class_entry *ce; zend_function *func; struct { uint32_t w1; uint32_t w2; } ww; } zend_value;
从 zend__value 中可以看出,long、double 类型直接存储值,而其它类型都为指针,指向各自的结构。所以,由于 zval 这样的结构,PHP 变量在声明的时候不用显示的指定其类型,因为不管你赋给变量什么类型的值,它都能帮你找到对应的存储结构。
以值为字符串的变量为例,其结构是这样的:
可以看到 php7 的 zval 总的只占 16 个字节,相比 PHP5 的 zval 所占用的 48 个字节节省了很大的内存。
此外,在 PHP5 中,所有的变量都在堆中申请,但是对于临时变量来说,没有必要在堆中申请。所以在 PHP7 中对此做了优化,临时变量是直接在栈中申请的。
下面介绍几个常见类型的变量结构,其他更多的类型,可自行查看源码。
对于整型和浮点型,由于其占用空间小,在 zval 中是直接存储的 整型的值是存在 lval 里,浮点型值则是存储在 dval 里。
typedef union _zend_value { zend_long lval; /* 整型*/ double dval; /* 浮点型 */ ... }
PHP 7 中定义了新的字符串结构体。结构如下:
struct _zend_string { zend_refcounted_h ; zend_ulong h; /* hash value */ size_t len; char val[1]; };
上面各个字段的意思:
gc: 变量引用信息,所有用到引用计数的变量类型都会有这个结构。
h: 哈希值,数组中计算索引时会用到。(据说这个操作为 PHP7 提高了 5% 的性能)
len: 字符串长度,通过这个值保证二进制安全
val: 字符串内容,变长struct,分配时按len长度申请内存
数组
array 是 PHP 中非常强大的一个数据结构,它的底层实现就是普通的有序HashTable,这里简单看下它的结构。后续再具体深入。
typedef struct _zend_array HashTable; struct _zend_array { zend_refcounted_h gc; union { struct { ZEND_ENDIAN_LOHI_4( zend_uchar flags, zend_uchar nApplyCount, zend_uchar nIteratorsCount, zend_uchar consistency) } v; uint32_t flags; } u; uint32_t nTableMask; Bucket *arData; uint32_t nNumUsed; uint32_t nNumOfElements; uint32_t nTableSize; uint32_t nInternalPointer; zend_long nNextFreeElement; dtor_func_t pDestructor; }
PHP7 的对象结构也是重新设计了,和 PHP5 的实现有了很大的不同。
struct _zend_object { zend_refcounted_h gc; uint32_t handle; zend_class_entry *ce; const zend_object_handlers *handlers; HashTable *properties; zval properties_table[1]; };
这里介绍下其中几个字段:
gc:gc头部
*ce:对象对应的 class 类
*properties :HashTable结构,key 为对象的属性名,value 是属性值在properties_tables数组中的偏移量,通过偏移量在 properties_talbe 找到对应的属性值。
properties_talbe[1]:存储对象的属性值
ok,先写这到这里。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
php构造方法__construct()的介绍:1、构造方法__construct()是一种结构特有的特殊方法。2、由系统规定,开发人员在定义时只需写一次,有构造方法的类在实例化对象后,对象自动调用。
Swoole可以广泛应用于互联网、移动通信、企业软件、网络游戏、物联网、车联网、智能家庭等领域。 使用PHP+Swoole作为网络通信框架,可以使企业IT研发团队的效率大大提升,更加专注于开发创新产品。
今天小编就为大家分享一篇使用laravel根据用户类型来显示或隐藏字段,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
对象输出:__toString()当一个对象被当做字符串进行输出时(echo,print),会调用__toString()方法<?php//输出对象classPerson{//属性public$name;private$age;//方法publicfunction
很多朋友想要知道PHP怎么样快速导出百万级数据到CSV或者EXCEL文件中,因此,这篇文章就给大家分享一下php百万级数据导出的操作,下面是导出思路,导出源码以及测试,有需要的朋友可以看一下,希望大家有收获。
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008