PHP面试知识复习(一):引用变量

引用变量

概念

变量

我的理解是,变量是一个能存放数据的容器,通过不同的变量名来区分不同的容器

引用变量

我的理解是,告诉解释器,这个变量名指向的容器和另一个特定的变量名一样

工作原理

PHP有两种赋值方式:传值赋值引用赋值

传值赋值

1
2
3
4
<?php
$a = 2;
$b = $a;
?>

解释器执行第1句的时候,会开辟一块内存空间,标记为a,将2存进去;执行第2句时,开辟另一块内存空间,标记为b,把a的值取出来,存进去

引用赋值

1
2
3
4
<?php
$a = 2;
$b = &$a;
?>

解释器执行第1句的时候,会开辟一块内存空间,标记为a,将2存进去;执行第2句时,会在标记为a的内存空间上,再加一个标记b

区别

两者的区别非常明显:

  • 赋值
    • 传值赋值时,改变a的值,b的值不会受到影响,因为值存放在不同的内存空间;
    • 引用赋值时,改变a的值,b的值也会随之改变,因为两个变量都是表示的同一块内存空间,只是名字不同而已
  • 销毁变量
    • 在a、b共用同一个空间时,如果销毁变量b,变量a不受影响,因为空间还有另一个名字,程序不会回收空间,所以变量a可以正常取值。

验证

PHP本身提供了查询当前使用内存的函数memory_get_usage(),在变量赋值前后打印使用内存,可以明显看出两者的差别

真题

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
/**
* 写出程序的输出结果
* 程序运行时,每一次循环结束后变量 $data 的值是什么?请解释
* 程序执行完成后,变量 $data 的值是什么?请解释
*/
$data = ['a', 'b', 'c'];
foreach ($data as $key => $val)
{
$val = &$data[$key];
var_dump($data);
}
?>

解答

因为PHP执行语句是按照顺序执行的,分析也要按照顺序来:

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

一个包含3个元素的数组

1
foreach ($data as $key => $val)

看到使用foreach遍历语句时,根据元素个数,确认需要执行3次,所以要分三次查看情况:

循环1

1
foreach ($data as $key => $val)

新增了两个变量
key: 0,val: a

1
$val = &$data[$key];

将val原来的空间丢掉,改成了指向data[0]

1
var_dump($data);

这时data 的值:[a, b, c]

循环2

1
foreach ($data as $key => $val)

因为val现在指向了data[0],当foreach语句将data[1]的值赋给val时,data[0]的值也改变了(因为用的同一个空间),所以data的值发生了变化:[b, b, c]

变量情况
key:1,val:b,data: [b, b, c]

1
$val = &$data[$key];

这时将val改为指向data[1]

1
var_dump($data);

这时data的值:[b, b, c]

循环3

1
foreach ($data as $key => $val)

因为val现在指向了data[1],当foreach语句将data[2]的值赋给val时,data[1]的值也改变了(因为用的同一个空间),所以data的发生了变化:[b, c, c]

1
$val = &$data[$key];

这时将val改为指向data[2]

1
var_dump($data);

这时data的值是:[b, c, c]

打印结果

[a, b, c]
[b, b, c]
[b, c, c]