快速业务通道

深入PHP使用技巧之变量

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-05-23
但也很难维护~指针可以说是C语言程序员心头的痛(当然也是福~^_^)。还有一种更高级更有效的方法是采用引用计数(Reference counting)。

  在PHP中,也可以采用引用来解决这样的问题,但你见过采用在PHP中大量使用引用的吗?显然很少。

  在PHP内核中,Zval的实现正是采用了引用计数的概念,说起引用计数就不得不谈到copy-on-write 机制。这样前面谈到的refcount和is_ref就有作用了。

  refcount:引用次数。在zval初始创建的时候就为1。每增加一个引用,则refcount ++。

  is_ref:用于表示一个zval是否是引用状态。zval初始化的情况下会是0,表示不是引用。

  在Zend/Zend.h内部有一些关于ZVAL的宏定义,里面比较清晰的解析了引用计数的一些规则,其中重点关注以下几个宏定义

  #define INIT_PZVAL(z) \

  (z)->refcount = 1; \

  (z)->is_ref = 0;

  #define SEPARATE_ZVAL_IF_NOT_REF(ppzv) \//非引用下的变量分离

  if (!PZVAL_IS_REF(*ppzv)) { \

  SEPARATE_ZVAL(ppzv); \

  }

  #define SEPARATE_ZVAL_TO_MAKE_IS_REF(ppzv) \//非引用下的变量分离,并且设置引用

  if (!PZVAL_IS_REF(*ppzv)) { \

  SEPARATE_ZVAL(ppzv); \

  (*(ppzv))->is_ref = 1; \

  }

  #define SEPARATE_ARG_IF_REF(varptr) \ //引用下的变量分离

  if (PZVAL_IS_REF(varptr)) { \

  zval *original_var = varptr; \

  ALLOC_ZVAL(varptr); \

  varptr->value = original_var->value; \

  varptr->type = original_var->type; \

  varptr->is_ref = 0; \

  varptr->refcount = 1; \

  zval_copy_ctor(varptr); \

  } else { \

  varptr->refcount++; \

  }

  这里面谈到两个重要的概念:

  1、非引用下的变量分离。

  非引用下的变量分离,是指在一堆非引用变量中插入引用的情况下,在PHP内部进行的一种内存操作。以下面的列子来看:

  $a = 1;

  $b = $a;

  $c = &$b;

  在前两句执行之后,内存结构如下图

  

\

 

  在第三句 $c = &$b;语句中则会执行“非引用下的变量分离。”,具体步骤是:

  将b分离出来,同时把a对应的zval的refcount-1。

  copy 出一个新的zval,并把zval的is_ref设置成1.

  把C指向这个新的zval,同时refcount ++

  最终效果如下图:

  

\

 

  2、引用下的变量分离。

  引用下的变量分离,是指在一堆引用变量中进行一个非引用赋值操作,这个时候会直接执行copy内存的操作。

  以下面的例子来说

  $a = 1;

  $b = &$a;

  $c = $b;

  在执行完前两行后,PHP中内存结构如下:

  

\

 

  在第三句,则会执行“引用下的变量分离”也就是真正的copy,最终内存结构如下图

  

\

 

  据此,基本上对PHP变量内部的一些原理比较清楚了,但还有一些需要注意点的:

  1、PHP变量的引用计数特性,对于数组同样也存在。但注意,对于key则不生效。(具体在后面章节会分析到。)

  2、PHP变量中的对象比较特殊,在PHP5之后,默认都是采用引用赋值的方式。具体实现可以参考Zend_objects.*系列代码。

  3、对于分析PHP内部变量,推荐采用xdebug_debug_zval,而不要采用内置的debug_zval_dump。因为PHP内置的debug_zval_dump函数一方面无法处理is_ref,而且采用了引用的方式来处理,从而导致看到结果会有误解。

  使用技巧结论

  据此可以得出分析出不少结论:

  1、在PHP开发中不推荐采用引

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号