设为首页 收藏本站
查看: 1002|回复: 0

[经验分享] [译]变量在 PHP7 内部的实现(一)

[复制链接]

尚未签到

发表于 2018-12-13 13:11:40 | 显示全部楼层 |阅读模式
翻译  Dec 10, 2015
  本文第一部分和第二均翻译自Nikita Popov(nikicPHP 官方开发组成员柏林科技大学的学生) 的博客。为了更符合汉语的阅读习惯文中并不会逐字逐句的翻译。
  要理解本文你应该对 PHP5 中变量的实现有了一些了解本文重点在于解释 PHP7 中 zval 的变化。
  由于大量的细节描述本文将会分成两个部分第一部分主要描述 zval(zend value) 的实现在 PHP5 和 PHP7 中有何不同以及引用的实现。第二部分将会分析单独类型strings、objects的细节。
PHP5 中的 zval
  PHP5 中 zval 结构体定义如下
typedef struct _zval_struct {  
    zvalue_value value;
  
    zend_uint refcount__gc;
  
    zend_uchar type;
  
    zend_uchar is_ref__gc;} zval;
  如上zval 包含一个 value、一个 type 以及两个 __gc 后缀的字段。value 是个联合体用于存储不同类型的值
typedef union _zvalue_value {  
    long lval;                 // 用于 bool 类型、整型和资源类型    double dval;               // 用于浮点类型    struct {                   // 用于字符串        char *val;
  
        int len;
  
    } str;
  
    HashTable *ht;             // 用于数组    zend_object_value obj;     // 用于对象    zend_ast *ast;             // 用于常量表达式(PHP5.6 才有)} zvalue_value;
  C 语言联合体的特征是一次只有一个成员是有效的并且分配的内存与需要内存最多的成员匹配也要考虑内存对齐。所有成员都存储在内存的同一个位置根据需要存储不同的值。当你需要 lval 的时候它存储的是有符号整形需要 dval 时会存储双精度浮点数。
  需要指出的是是联合体中当前存储的数据类型会记录到 type 字段用一个整型来标记
#define IS_NULL     0      /* Doesn't use value */#define IS_LONG     1      /* Uses lval */#define IS_DOUBLE   2      /* Uses dval */#define IS_BOOL     3      /* Uses lval with values 0 and 1 */#define IS_ARRAY    4      /* Uses ht */#define IS_OBJECT   5      /* Uses obj */#define IS_STRING   6      /* Uses str */#define IS_RESOURCE 7      /* Uses lval, which is the resource ID *//* Special types used for late-binding of constants */#define IS_CONSTANT 8  
#define IS_CONSTANT_AST 9
PHP5 中的引用计数
  在PHP5中zval 的内存是单独从堆heap中分配的有少数例外情况PHP 需要知道哪些 zval 是正在使用的哪些是需要释放的。所以这就需要用到引用计数zval 中 refcount__gc 的值用于保存 zval 本身被引用的次数比如 $a = $b = 42 语句中42 被两个变量引用所以它的引用计数就是 2。如果引用计数变成 0就意味着这个变量已经没有用了内存也就可以释放了。
  注意这里提及到的引用计数指的不是 PHP 代码中的引用使用 &而是变量的使用次数。后面两者需要同时出现时会使用『PHP 引用』和『引用』来区分两个概念这里先忽略掉 PHP 的部分。
  一个和引用计数紧密相关的概念是『写时复制』对于多个引用来说zaval 只有在没有变化的情况下才是共享的一旦其中一个引用改变 zval 的值就需要复制”separated”一份 zval然后修改复制后的 zval。
  下面是一个关于『写时复制』和 zval 的销毁的例子

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-650971-1-1.html 上篇帖子: PHP整理笔记六自定义函数 下篇帖子: [译]变量在 PHP7 内部的实现(二)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表