|  | 
|  | 1 | +## 7.7 zval的操作 | 
|  | 2 | +扩展中经常会用到各种类型的zval,PHP提供了很多宏用于不同类型zval的操作,尽管我们也可以自己操作zval,但这并不是一个好习惯,因为zval有很多其它用途的标识,如果自己去管理这些值将是非常繁琐的一件事,所以我们应该使用PHP提供的这些宏来操作用到的zval。 | 
|  | 3 | + | 
|  | 4 | +本节提到的zval泛指zval及各种zend_value。 | 
|  | 5 | + | 
|  | 6 | +### 7.7.1 生成不同类型的zval | 
|  | 7 | +PHP7将变量的引用计数转移到了具体的value上,所以zval更多的是作为统一的传输格式,很多情况下只是临时性使用,比如函数调用时的传参,最终需要的数据是zval携带的zend_value,函数从zval取得zend_value后就不再关心zval了,这种就可以直接在栈上分配zval。分配完zval后需要将其设置为我们需要的类型以及设置其zend_value,PHP中定义的`ZVAL_XXX()`系列宏就是用来干这个的,这些宏第一个参数z均为要设置的zval的指针,后面为要设置的zend_value。 | 
|  | 8 | + | 
|  | 9 | +* __ZVAL_UNDEF(z):__ 表示zval被销毁 | 
|  | 10 | +* __ZVAL_NULL(z):__ 设置为NULL | 
|  | 11 | +* __ZVAL_FALSE(z):__ 设置为false | 
|  | 12 | +* __ZVAL_TRUE(z):__ 设置为true | 
|  | 13 | +* __ZVAL_BOOL(z, b):__ 设置为布尔型,b为IS_TRUE、IS_FALSE,与上面两个等价 | 
|  | 14 | +* __ZVAL_LONG(z, l):__ 设置为整形,l类型为zend_long,如:`zval z; ZVAL_LONG(&z, 88);` | 
|  | 15 | +* __ZVAL_DOUBLE(z, d):__ 设置为浮点型,d类型为double | 
|  | 16 | +* __ZVAL_STR(z, s):__ 设置字符串,将z的value设置为s,s类型为zend_string*,不会增加s的refcount,支持interned strings | 
|  | 17 | +* __ZVAL_NEW_STR(z, s):__ 同ZVAL_STR(z, s),s为普通字符串,不支持interned strings | 
|  | 18 | +* __ZVAL_STR_COPY(z, s):__ 将s拷贝到z的value,s类型为zend_string*,同ZVAL_STR(z, s),这里会增加s的refcount | 
|  | 19 | +* __ZVAL_ARR(z, a):__ 设置为数组,a类型为zend_array* | 
|  | 20 | +* __ZVAL_NEW_ARR(z):__ 新分配一个数组,主动分配一个zend_array | 
|  | 21 | +* __ZVAL_NEW_PERSISTENT_ARR(z):__ 创建持久化数组,通过malloc分配,需要手动释放 | 
|  | 22 | +* __ZVAL_OBJ(z, o):__ 设置为对象,o类型为zend_object* | 
|  | 23 | +* __ZVAL_RES(z, r):__ 设置为资源,r类型为zend_resource* | 
|  | 24 | +* __ZVAL_NEW_RES(z, h, p, t):__ 新创建一个资源,h为资源handle,t为type,p为资源ptr指向结构 | 
|  | 25 | +* __ZVAL_REF(z, r):__ 设置为引用,r类型为zend_reference* | 
|  | 26 | +* __ZVAL_NEW_EMPTY_REF(z):__ 新创建一个空引用,没有设置具体引用的value | 
|  | 27 | +* __ZVAL_NEW_REF(z, r):__ 新创建一个引用,r为引用的值,类型为zval* | 
|  | 28 | +* ... | 
|  | 29 | + | 
|  | 30 | +### 7.7.2 获取zval的值 | 
|  | 31 | + | 
|  | 32 | +### 7.7.3 引用计数 | 
|  | 33 | + | 
0 commit comments