引用是PHP中比较特殊的一种类型,它实际是指向另外一个PHP变量,对它的修改会直接改动实际指向的zval,可以简单的理解为C中的指针,在PHP中通过&
操作符产生一个引用变量,也就是说不管以前的类型是什么,&
首先会创建一个zend_reference
结构,其内嵌了一个zval,这个zval的value指向原来zval的value(如果是布尔、整形、浮点则直接复制原来的值),然后将原zval的类型修改为IS_REFERENCE,原zval的value指向新创建的zend_reference
结构。
struct _zend_reference {
zend_refcounted_h gc;
zval val;
};
结构非常简单,除了公共部分zend_refcounted_h
外只有一个val
,举个示例看下具体的结构关系:
$a = "time:" . time(); //$a -> zend_string_1(refcount=1)
$b = &$a; //$a,$b -> zend_reference_1(refcount=2) -> zend_string_1(refcount=1)
最终的结果如图:
注意:引用只能通过&
产生,无法通过赋值传递,比如:
$a = "time:" . time(); //$a -> zend_string_1(refcount=1)
$b = &$a; //$a,$b -> zend_reference_1(refcount=2) -> zend_string_1(refcount=1)
$c = $b; //$a,$b -> zend_reference_1(refcount=2) -> zend_string_1(refcount=2)
//$c -> ---
$b = &$a
这时候$a
、$b
的类型是引用,但是$c = $b
并不会直接将$b
赋值给$c
,而是把$b
实际指向的zval赋值给$c
,如果想要$c
也是一个引用则需要这么操作:
$a = "time:" . time(); //$a -> zend_string_1(refcount=1)
$b = &$a; //$a,$b -> zend_reference_1(refcount=2) -> zend_string_1(refcount=1)
$c = &$b;/*或$c = &$a*/ //$a,$b,$c -> zend_reference_1(refcount=3) -> zend_string_1(refcount=1)
这个也表示PHP中的 引用只可能有一层 ,不会出现一个引用指向另外一个引用的情况 ,也就是没有C语言中指针的指针
的概念。