• php扩展开发学习笔记 4

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://syre.blogbus.com/logs/13799898.html

    zval和zvalue_value

      之前一直跳过的数组和对象,以及需要返回或者处理多种类型时,都需要了解php内部是如何保存值的。

      php内部保存值的基本单位是zval。它的C结构定义如下:

    typedef struct _zval_struct {
        zvalue_value value;
        zend_uint refcount;
        zend_uchar type;
        zend_uchar is_ref;
    } zval;

    其中is_ref表示这个值是否是一个引用。
    type表示值类型:有IS_NULL、IS_BOOL、IS_LONG、IS_DOUBLE、IS_STRING、IS_ARRAY、IS_OBJECT、IS_RESOURCE这8种。
    refcount表示引用计数。
    value存放这个zval的值。

      在判断一个zval的值时,可以用如下的代码:

    zval *a;
    ...
    if (Z_TYPE_P(a) == IS_LONG){
        ...
    }

      zvalue_value中保存了zval的值,它的C结构定义如下:

    typedef union _zvalue_value {
        long lval;
        double dval;
        struct {
            char *val;
            int len;
        } str;
        HashTable *ht;
        zend_object_value obj;
    } zvalue_value;

      这是一个union型,其中的lval、dval、str、ht、obj分别表示整数、浮点、字符串、数组、对象。

      取 得一个zval的值当然也可以直接从它的value里直接取,不过更好的办法是通过一套宏来获取。Z_BVAL、Z_LVAL_P、Z_DVAL_PP这 样的形式。都以Z_开头,后面是类型,B就是boolean,L就是long,D就是double。后面可选的_P,_PP表示指针的层次。带_P是用来 取zval*的,带_PP是用来去zval**的。这些宏返回的就是这个zval的值所对应的C类型。对于字符串,则有两组宏Z_STRVAL、 Z_STRLEN。后面当然也可以加_P和_PP。分别返回char*和字符串的长度。这些宏使用很简单,例如:

    zval* a;
    ...
    long n;
    n = Z_LVAL_P(a);

      前面用到的Z_TYPE_P其实也是一个类似的宏,用于取得zval*的类型


    历史上的今天:

    Tags: PHP C 扩展
    Trackback: