什么是引用变量?
在PHP中引用意味着用不同的名字访问同一个变量内容
定义方式:
使用&符号
1、普通变量赋值依据cow机制,
1.1 vim demo1.php
<?
//定义一个变量
$a = range(0,1000);
var_dump(memory_get_usage());
//定义一个变量b,将a变量赋值给b
//根据cow copy on wirte 机制,如果a没有被重新进行写操作,b不会开辟新的内存空间
$b = $a;
var_dump(memory_get_usage());//对比第一次,内存不会有明显变化
//对a进行修改
$a = range(0,1000);
var_dump(memory_get_usage());//由于对a重新赋值,b也被赋予新的内存空间
?>
运行结果:
[root@chen php]# php demo1.php
int(366104)
int(366240)
int(510744)
1.2 x_debug_zval显示变量的引用情况
<?php
$a = range(0,10);
xdebug_debug_zval('a');
$b = $a;
xdebug_debug_zval('a');
$a = range(0,10);
xdebug_debug_zval('a');
运行结果:
a: (refcount=1, is_ref=0)=array (0 => (refcount=1, is_ref=0)=0, 1 => (refcount=1, is_ref=0)=1, 2 => (refcount=1, is_ref=0)=2, 3 => (refcount=1, is_ref=0)=3, 4 => (refcount=1, is_ref=0)=4, 5 => (refcount=1, is_ref=0)=5, 6 => (refcount=1, is_ref=0)=6, 7 => (refcount=1, is_ref=0)=7, 8 => (refcount=1, is_ref=0)=8, 9 => (refcount=1, is_ref=0)=9, 10 => (refcount=1, is_ref=0)=10)
a: (refcount=2, is_ref=0)=array (0 => (refcount=1, is_ref=0)=0, 1 => (refcount=1, is_ref=0)=1, 2 => (refcount=1, is_ref=0)=2, 3 => (refcount=1, is_ref=0)=3, 4 => (refcount=1, is_ref=0)=4, 5 => (refcount=1, is_ref=0)=5, 6 => (refcount=1, is_ref=0)=6, 7 => (refcount=1, is_ref=0)=7, 8 => (refcount=1, is_ref=0)=8, 9 => (refcount=1, is_ref=0)=9, 10 => (refcount=1, is_ref=0)=10)
a: (refcount=1, is_ref=0)=array (0 => (refcount=1, is_ref=0)=0, 1 => (refcount=1, is_ref=0)=1, 2 => (refcount=1, is_ref=0)=2, 3 => (refcount=1, is_ref=0)=3, 4 => (refcount=1, is_ref=0)=4, 5 => (refcount=1, is_ref=0)=5, 6 => (refcount=1, is_ref=0)=6, 7 => (refcount=1, is_ref=0)=7, 8 => (refcount=1, is_ref=0)=8, 9 => (refcount=1, is_ref=0)=9, 10 => (refcount=1, is_ref=0)=10)
屏幕快照 2017-10-24 上午10.32.32.png
2、使用引用赋值
2.1 vim demo2.php
<?
//定义一个变量
$a = range(0,10);
var_dump(memory_get_usage());
//定义一个变量b,将a变量赋值给b
//根据cow copy on wirte 机制,如果a没有被重新进行写操作,b不会开辟新的内存空间
$b = &$a;
var_dump(memory_get_usage());
//对a进行修改
$a = range(0,10);
var_dump(memory_get_usage());
?>
运行结果:
[root@chen php]# php demo2.php
int(223352)
int(223488)
int(223464)
结果显示,使用引用后,b就指向a的内存地址,a被重新写入,b的值也不会变化。
2.2 x_debug_zval显示变量的引用情况
<?php
$a = range(0,10);
xdebug_debug_zval('a');
$b = &$a;
xdebug_debug_zval('a');
$a = range(0,10);
xdebug_debug_zval('a');
运行结果:
a: (refcount=1, is_ref=0)=array (0 => (refcount=1, is_ref=0)=0, 1 => (refcount=1, is_ref=0)=1, 2 => (refcount=1, is_ref=0)=2, 3 => (refcount=1, is_ref=0)=3, 4 => (refcount=1, is_ref=0)=4, 5 => (refcount=1, is_ref=0)=5, 6 => (refcount=1, is_ref=0)=6, 7 => (refcount=1, is_ref=0)=7, 8 => (refcount=1, is_ref=0)=8, 9 => (refcount=1, is_ref=0)=9, 10 => (refcount=1, is_ref=0)=10)
a: (refcount=2, is_ref=1)=array (0 => (refcount=1, is_ref=0)=0, 1 => (refcount=1, is_ref=0)=1, 2 => (refcount=1, is_ref=0)=2, 3 => (refcount=1, is_ref=0)=3, 4 => (refcount=1, is_ref=0)=4, 5 => (refcount=1, is_ref=0)=5, 6 => (refcount=1, is_ref=0)=6, 7 => (refcount=1, is_ref=0)=7, 8 => (refcount=1, is_ref=0)=8, 9 => (refcount=1, is_ref=0)=9, 10 => (refcount=1, is_ref=0)=10)
a: (refcount=2, is_ref=1)=array (0 => (refcount=1, is_ref=0)=0, 1 => (refcount=1, is_ref=0)=1, 2 => (refcount=1, is_ref=0)=2, 3 => (refcount=1, is_ref=0)=3, 4 => (refcount=1, is_ref=0)=4, 5 => (refcount=1, is_ref=0)=5, 6 => (refcount=1, is_ref=0)=6, 7 => (refcount=1, is_ref=0)=7, 8 => (refcount=1, is_ref=0)=8, 9 => (refcount=1, is_ref=0)=9, 10 => (refcount=1, is_ref=0)=10)
屏幕快照 2017-10-24 上午10.45.09.png
3、引用的销毁 unset
注意:unset只会取消引用,不会销毁空间
示例:
vim demo5.php
<?php
<?php
$a = 1;
$b = &$a;
unset($b);
echo $a."\n";
运行结果:
[root@chen php]# php demo5.php
1
对象本省就是引用传值,不需要引用符号
示例1:
<?php
class Person{
public $name = 'chenzhitao';
}
$p1 = new Person;
xdebug_debug_zval('p1');
$p2 = $p1;
xdebug_debug_zval('p1');
$p2->name = 'Jason';
xdebug_debug_zval('p1');
运行结果:
[root@chen php]# php demo6.php
p1: (refcount=1, is_ref=0)=class Person { public $name = (refcount=2, is_ref=0)='chenzhitao' }
p1: (refcount=2, is_ref=0)=class Person { public $name = (refcount=2, is_ref=0)='chenzhitao' }
p1: (refcount=2, is_ref=0)=class Person { public $name = (refcount=1, is_ref=0)='Jason' }
屏幕快照 2017-10-24 上午10.59.57.png
示例2:
<?php
/**
* 写出如下程序的输出结果
* <?php
*
* $data = ['a', 'b', 'c'];
*
* foreach($data as $key => $val)
* {
* $val = &$data[$key];
* }
* 程序运行时,每一次循环结束后变量$data的值是什么?请解释
* 程序执行完成后,变量$data的值是什么?请解释
*/
$data = ['a', 'b', 'c'];
foreach ($data as $key=>$val)
{
$val = &$data[$key];
var_dump($data);
}
var_dump($data);
运行结果:
[0]=>
&string(1) "a"
[1]=>
string(1) "b"
[2]=>
string(1) "c"
}
array(3) {
[0]=>
string(1) "b"
[1]=>
&string(1) "b"
[2]=>
string(1) "c"
}
array(3) {
[0]=>
string(1) "b"
[1]=>
string(1) "c"
[2]=>
&string(1) "c"
}
array(3) {
[0]=>
string(1) "b"
[1]=>
string(1) "c"
[2]=>
&string(1) "c"
}
网友评论