快速业务通道

深入PHP使用技巧之变量

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-05-23

  众所周知,PHP与其他脚本语言一样,属于弱变量类型的语言。同时PHP本身也是通过C语言来实现。本文主要介绍PHP内部是如何实现弱变量类型的,并且据此分析在PHP开发中需要注意的一些使用技术。其中会重点分析PHP中的copy on write机制和引用相关方面的话题。 本章节属于《深入PHP使用技巧》的第一部分。

  如何实现弱变量

  在了解PHP实现弱变量类型之前,可以先思考下:如何通过C/C++来实现弱变量类型的效果呢?

  这个问题我在BIT培训课上基本上有两种答案:

  方法1:采用C++的继承机制。首先定义一个基础类型

  Class Var

  {

  }

  然后基于Var,派生出不同的子类型IntVar/FloatVar/StringVar等等。

  方法2:基于C语言的 Struct。其中一个字段用于标识类型,另外一个字段用于存储数据,由于数据要是各种类型,所以通常需要采用指针

  比如:

  struct var {

  Int type;

  Void *data;

  };

  两种思路本身并没有太大区别,也都基本上能够满足需求。在PHP中采用了第二种思路,并且做了比较多的优化。在PHP中,所有的变量都会对应同一种类型zval,其中zval也就是struct _zval_struct,具体定义如下:

  typedef union _zvalue_value {

  long lval; /* long value */

  double dval; /* double value */

  struct {

  char *val;

  int len;

  } str;

  HashTable *ht; /* hash table value */

  zend_object_value obj;

  } zvalue_value;

  struct _zval_struct {

  /* Variable information */

  zvalue_value value; /* value */

  zend_uint refcount;

  zend_uchar type; /* active type */

  zend_uchar is_ref;

  };

  从zval可以看出,PHP在细节方面的确做了不少优化的功夫。

  1.zend_uchar type。采用uchar节省内存。

  2.zvalue_value value; 采用union来替换void *,这样同样能节省空间,并且比void *更能表义清晰。

  3.在字符串类型中,默认保留了字符串的长度。这样很容易做到字符串的二进制安全,并且在计算字符串长度的时候不需要进行扫描。

  观察PHP弱变量的实现,也会有以下疑惑:

  1.为什么会没有int类型呢?其实在PHP中是有的,只是说默认int数据就保存在long中。

  2.资源类型咋表现的呢?资源在PHP内部其实就是一数字。详细后续会介绍。

  3.refcount和is_ref是干嘛的呢?呵呵,这就是第二部分要介绍的了。

  Reference counting & Copy-on-Write

  PHP和其他语言类似,在其语法中有两种赋值方式:引用赋值和非引用赋值(普通的==赋值)。

  <?php

  $a = 1;

  $b = $a;//非引用赋值

  $c = &$a;//引用赋值

  ?>

  引用赋值和非引用赋值在PHP内部是如何实现的呢?一种通常的认识是:“引用赋值就是两个变量对应同一个Zval,非引用赋值则是直接产生一个新的zval,同时把对应的值直接copy过来。”也就是该代码的内存结构如下:

  

\

 

  (该图是大多数人认为的PHP内存结构,是错误的)

  这样的确能够满足大部分情况下的需求,但显然不是最佳的解决方案,尤其是在内存管理上,比如说以下代码就会显得非常的低效。

  <?php

  $arr = array(...);//定义一个非常大的PHP数组

  myfunc($arr);//每一个函数调用都是一次隐性的非引用赋值

  myfunc($arr);

  ?>

  因为每次函数调用会进行一次内存dump,而大内存的内存dump是非常耗CPU的。在C语言中,一种解决方案是采用指针,所有函数调用尽量传递指针。的确很灵活高效,

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站: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号