【PHP常见面试题 PHP基础-引用变量】什么是 引用变量?在PHP当中,用什么符号定义引用变量?

一. PHP引用变量考察点

1. PHP的 引用变量 的概念 及 定义方式;

概念
	在PHP中,引用意味着用不同的名字访问同一个变量内容。
定义方式
	使用 & 符号

2. 延伸:PHP引用变量的原理

1)赋值:将一个变量的值赋值给另一个变量,其中一个变量的值进行改变,会重新进行拷贝,此时会再开辟一个新的内存空间。
// 1. 定义一个变量
$a = range(0, 1000); // 在内存中开辟一片空间,存储变量a
var_dump(memory_get_usage());

// 2. 定义变量 b,将 a变量的值赋值给 b
$b = $a; // 将变量b 指向 变量a开辟的空间中
var_dump(memory_get_usage());

// 3. 对 a进行修改
$a = range(0, 1000);
var_dump(memory_get_usage());

原理:使用了 COW(Copy On Write)机制 : 对 $a$b 其中一个进行改变,内存空间才会发生改变。

1)在内存中开辟一片空间存储变量a;
2)将变量b 指向 变量a的内存空间中;
3)对变量a进行修改(对a进行写操作),此时会再开辟一片内存空间存储$a和$b(原来的$a和$b被改变)
2)引用:两个变量无论何时都共用一个内存空间(对其中一个的值进行更改的时候,不会开辟新的内存空间)
// 1. 定义一个变量
$a = range(0, 1000);
var_dump(memory_get_usage());

// 2. 定义变量b, 将a变量的值赋值给b
$b = &$a;
var_dump(memory_get_usage());

// 3. 对a进行修改
$a = range(0, 1000);
var_dump(memory_get_usage());

原理:

1)定义一个变量a(开辟一个内存空间存储变量a);
2)定义变量$b,将$a的地址给了$b,此时$b与$a指向同一个内存空间,且永远指向该内存空间(不会再重新拷贝,改掉的只是该内存空间的值);
3)对a进行修改(不会再开辟内存空间),此时$a和$b的值,都是修改后的值;
3)unset 只会取消引用,不会销毁内存空间
$a = 1; // 开辟一个内存空间存储变量a,并赋值为1
$b = &$a; // 将$a的引用赋值给$b,此时$a和$b指向同一个内存空间(永久指向)
unset($b); // 此时取消的是$a和$b的引用,不会取消内存空间
echo $a.'<br>'; // 1
4) 对象本身就是引用传递,因此,在修改的时候,不会再重新开辟内存空间
class Person
{
    public $name = 'zhangsan';
}

$p1 = new Person; // 开辟一个内存空间存储$p1
$p2 = $p1; // 将$p1和$p2存入同一个内存空间(内存空间会变大)
$p2->name = 'lisi'; // $p1,$p2都为lisi,因为指向的是同一个内存空间

二. 真题

写出如下程序的输出结果:
$data = ['a', 'b', 'c'];

foreach ($data as $key => $val) { 
    $val = &$data[$key]; 
}

程序运行时,每一次循环结束后变量 $data的值时什么?请解释

程序执行完成后,变量 $data的值时什么?请解释

1)答案:

// 第一次循环
$data = ['a', 'b', 'c'];
// 第二次循环
$data = ['b', 'b', 'c'];
// 第三次循环
$data = ['b', 'c', 'c'];

// 程序执行完成后,变量 $data的值
$data = ['b', 'b', 'c'];

2)解析:

1)foreach ($data as $key => $val)
	会将$data第一个元素的键名赋值给$key,将$data的第一个元素的值赋值给$val(即$k=0; $v=a;)
2) $val = &$data[$key]; 
	$v = &$data[0];(即$v拿了$data[0]的地址)
	$v = &$data[0] = a(此时$data[0]和$v都指向 a内存空间)
	
以上步骤即为:
1)第一次循环:
	$k = 0;
	$v = a;
	$v = &$data[0];
	($v = &$data[0] = a,$v 和 $data[0] 都指向 a内存空间) // 结果:$data = ['a','b','c'];
2)第二次循环:
	$k = 1;
	$v = b;
	$data[0] = b;
	$v = &$data[1];
	($v = &$data[1] = b, $v 和 $data[1] 都指向 b内存空间) // 结果:$data = ['b','b','c'];
3)第三次循环:	
	$k = 2;
	$v = c;
	$data[1] = $c;
	$v = &$data[2];
	($v = &$data[2] = c, $v 和 $data[1] 都指向 c内存空间) // 结果:$data = ['b','c','c'];

3)代码测试:

$data = ['a', 'b', 'c'];

foreach ($data as $k => $v) {
    $v = &$data[$k];
    var_dump($data);
}
var_dump($data);

运行结果:

循环的执行结果

扫描二维码关注公众号,回复: 3792775 查看本文章

猜你喜欢

转载自blog.csdn.net/studyphp123/article/details/83387954