概念:
在PHP中引用变量意味着,使用不同的变量名去访问同一个变量的内容。
定义方式:使用 & 符号
demo1.php
<?php
//定义一个变量
$a = range(1,9999);
var_dump(memory_get_usage());//获取为变量开辟空间变化
//定义变量b 将变量a的值赋值给变量b
//cow 机制 copy on write
$b = $a;
var_dump(memory_get_usage());
//对变量a进行修改
$a = range(1,9999);
var_dump(memory_get_usage());
?>
总结:变量a发生了改变,因cow机制,会进行开辟内存空间,内存空间发生变化。
demo2.php
<?php
//定义一个变量
$a = range(1,9999);
var_dump(memory_get_usage());
//定义变量b 将变量a的值赋值给变量b
//cow 机制 copy on write
$b = &$a;
var_dump(memory_get_usage());
//对变量a进行修改
$a = range(1,9999);
var_dump(memory_get_usage());
?>
总结:demo2和demo1相比较,变量b 引用了变量a的地址空间,即使变量a发生了改变,空间也不会发生改变。
demo3.php(这个需要自己安装xdebug扩展)
<?php
//zval 变量容器
$a = range(0, 5);
xdebug_debug_zval('a');
//将变量a的值赋值给b
$b = $a;
xdebug_debug_zval('a');
$a = range(0, 5);
xdebug_debug_zval('a');
?>
运行结果:
a: (refcount=1, is_ref=0)=array (0 => (refcount=0, is_ref=0)=0, 1 => (refcount=0, is_ref=0)=1, 2 => (refcount=0, is_ref=0)=2, 3 => (refcount=0, is_ref=0)=3, 4 => (refcount=0, is_ref=0)=4, 5 => (refcount=0, is_ref=0)=5)
a: (refcount=2, is_ref=0)=array (0 => (refcount=0, is_ref=0)=0, 1 => (refcount=0, is_ref=0)=1, 2 => (refcount=0, is_ref=0)=2, 3 => (refcount=0, is_ref=0)=3, 4 => (refcount=0, is_ref=0)=4, 5 => (refcount=0, is_ref=0)=5)
a: (refcount=1, is_ref=0)=array (0 => (refcount=0, is_ref=0)=0, 1 => (refcount=0, is_ref=0)=1, 2 => (refcount=0, is_ref=0)=2, 3 => (refcount=0, is_ref=0)=3, 4 => (refcount=0, is_ref=0)=4, 5 => (refcount=0, is_ref=0)=5)
总结:将变量a赋值给变量b refcount值加1,此时为2,但是并没有引用;当变量a的值发生改变时,refcount从1开始,此时也没有引用 is_ref为0 即false。
demo4.php
<?php
//zval 变量容器
$a = range(0, 5);
xdebug_debug_zval('a');
//将变量a的值赋值给b
$b = &$a;
xdebug_debug_zval('a');
$a = range(0, 5);
xdebug_debug_zval('a');
?>
结果:
a: (refcount=1, is_ref=0)=array (0 => (refcount=0, is_ref=0)=0, 1 => (refcount=0, is_ref=0)=1, 2 => (refcount=0, is_ref=0)=2, 3 => (refcount=0, is_ref=0)=3, 4 => (refcount=0, is_ref=0)=4, 5 => (refcount=0, is_ref=0)=5)
a: (refcount=2, is_ref=1)=array (0 => (refcount=0, is_ref=0)=0, 1 => (refcount=0, is_ref=0)=1, 2 => (refcount=0, is_ref=0)=2, 3 => (refcount=0, is_ref=0)=3, 4 => (refcount=0, is_ref=0)=4, 5 => (refcount=0, is_ref=0)=5)
a: (refcount=2, is_ref=1)=array (0 => (refcount=0, is_ref=0)=0, 1 => (refcount=0, is_ref=0)=1, 2 => (refcount=0, is_ref=0)=2, 3 => (refcount=0, is_ref=0)=3, 4 => (refcount=0, is_ref=0)=4, 5 => (refcount=0, is_ref=0)=5)
总结:demo4相比较于demo3使用了引用,即变量b引用了变量a; 在引用之后refcount还是2,并不会开辟新的空间;
is_ref = 1; 说明使用了引用变量。
demo5.php
<?php
//unset只会取消引用,并不会销毁空间
$a = 1;
$b = &$a;
unset($b);
var_dump($a);
// echo $b; //b 此时已经进行了销毁
?>
总结:unset只会取消引用,但并不会销毁空间地址,因为此时打印出变量a的值是1。
demo6.php
<?php
//对象本身就是引用传值
class Person {
public $name = 'zhangsan';
}
$p1 = new Person();
xdebug_debug_zval('p1');
$p2 = $p1;
xdebug_debug_zval('p1');
$p2->name = 'lisi';
xdebug_debug_zval('p1');
?>
结果:
p1: (refcount=1, is_ref=0)=class Person { public name = (refcount=0, is_ref=0)='zhangsan' }
p1: (refcount=2, is_ref=0)=class Person { public $name = (refcount=0, is_ref=0)='lisi' }
总结:对象本身就是引用传值
example.php
<?php
$data = [a,b,c];
foreach ($data as $key => $value) {
$value = &$data[$key];
var_dump($data);
}
var_dump($data);
?>
结果:
/home/example.php:6:
array(3) {
[0] =>
string(1) "a"
[1] =>
string(1) "b"
[2] =>
string(1) "c"
}
/home/example.php:6:
array(3) {
[0] =>
string(1) "b"
[1] =>
string(1) "b"
[2] =>
string(1) "c"
}
/home/example.php:6:
array(3) {
[0] =>
string(1) "b"
[1] =>
string(1) "c"
[2] =>
string(1) "c"
}
/home/example.php:8:
array(3) {
[0] =>
string(1) "b"
[1] =>
string(1) "c"
[2] =>
string(1) "c"
}
网友评论