php zval结构体

typedef struct zval_struct{
    zval_value value;
    zend_uint ref_count;
    zend_uchar type;
    zend_uchar is_ref;
}

其中是真正保存数据的部分,定位为一个联合体(union)

typedef union _zvalue_value {
    long lval;
    double dval;
    struct {
        char *val;
        int len;
    } str;
    HashTable *ht;
    zend_object_value obj;
} zvalue_value;
写时复制
$a = 1;
$b = $a;
$b += 5;
  1. 复制一个和$b所指向zval一样的zavl;
  2. $b所指的zvalref_count减一;
  3. 初始化新的zval设置ref_count=1,is_ref=0;
  4. $b指向新的zval
写时改变
$a = 1;
$b = &$a;
$b += 5;
  1. 第一步和写时复制的第一步一样;
  2. 第二步$b所指向的zvalref_count+1,并将is_ref设置为1;
  3. $b变化时,会执行get_var_and_separate()函数看是否需要分离,如果is_ref会直接返回$b所指向的zval
  4. 再去修改$b的值,$a的值也会变,因为指向的都是同一个zval
写时分离
$a = 1;
$b = $a;
$c = &$a;

如果一个zval结构体既有ref_countis_ref
Zend会将等号右边的变量分离出来一个新的zval

global$_GOLBAL['a']
  • global是全局作用域a的引用

  • $_GOLBAL['a']是全局作用域a的本身

你可能感兴趣的:(PHP)