在PHP 中引用的意思是用不同的名字访问同一个变量内容。与在C语言中的指针不同:例如不能对引用做指针运算,引用并不是实际的内存地址
PHP内核的角度:1
2
3
4
5
6struct _zval_struct {
zvalue_value value; // 存储变量的值
zend_uint refcount__gc; //表示引用计数 默认为:1
zend_uchar type; // 变量具体的类型
zend_uchar is_ref__gc; //表示是否为引用
};
举例:
$a = 10;
$b = $a;
这时$b没有引用,只是将$a的值赋给了$b,那么zval这个结构中的refcount__gc就变为2了,而is_ref__gc还是false,表示未引用,因为内核$a已经开辟了一块内存空间,当$a赋值给$b时,$b的值只指向了$a,这样就省去了重新开辟一块内存,但是当$b值被改变时($a的值不会变),$b又将会开辟一块新的内存空间,这就是所谓的写时复制。下面就讲下引用:
$a = 10;
$b = &$a;
这个时候,内核中存储$a的结构is_ref__gc标记为true,代表是引用,那么$a和$b都指向了同一个内存地址,当$b=20的时候,$a也会变成20
1 | <?php |
函数的传址调用:
1 | function test(&$a) { |
函数的引用返回:
1 | function &test() { |
通过$a=&test(); 方式得到的才是函数的引用返回
$a=test()方式调用函数,只是将函数的值赋给$a而已, 而$a做任何改变 都不会影响到函数中的$b
而通过$a=&test()方式调用函数呢, 他的作用是 将return $b中的 $b变量的内存地址与$a变量的内存地址 指向了同一个地方
即产生了相当于这样的效果($a=&b;) 所以改变$a的值 也同时改变了$b的值 所以在执行了
$a=&test();
$a=5;
以后,$b的值变为了5
对象的调用
1 | <?php |
在PHP中,对象的复制是通过引用来实现的。
上列中$b=new a; $c=$b; 其实等效于$b=new a; $c=&$b;
PHP中默认就是通过引用来调用对象, 但有时你可能想建立一个对象的副本,并希望原来的对象的改变不影响到副本。
为了这样的目的,PHP定义了一个特殊的方法,称为__clone.