PHP引用(&)的考察点

时间:2021-05-30 12:22:14

引用的概念

在PHP中引用意味着用不同的名字访问同一个变量内容。

定义方式

使用 & 符号来表示

变量的引用

$a = 'ABC'; //开辟一块内存空间存储数据,$a指向该空间
$b = &$a; //创建引用变量,此时$b也指向上述空间
echo $b; //输出ABC
$b = 'EFG'; //
echo $a; //输出EFG,$a 和 $b指向的是同一个变量,修改的是同一个变量

值得注意的是,PHP有一个COW机制(copy on wrtite):

$a = 'ABC';
$b = $a; //此时并没有使用引用变量,但是由于COW机制,$b 仍然指向$a的空间
$b = 'ABC'; //此时对$b 进行 了写操作 ,触发cow,$b指向新的空间,$a不发生变化

函数引用

对于函数的引用,值得一提的是,必须在申明和调用时都加上&才算是真正的引用。

<?php
function &test(){ 
    static $b=0;//申明一个静态变量 
    $b=$b+1; 
    echo $b; 
    return $b; }
}
$a=test();//这条语句会输出 $b的值 为1 
$a=5; $a=test();//这条语句会输出 $b的值 为2
$a=&test();//这条语句会输出 $b的值 为3 
$a=5; $a=test();//这条语句会输出 $b的值 为6
?>

如果只使用$a=test(),其实和普通的函数调用是一样的,只是获得了函数的返回值,而使用$a=&test()方式来调用,则$a指向了$b的地址,改变$a的值,也会改变$b的值。

对象的引用

<?php
class a{
    var $abc="ABC";
} 
$b=new a; 
$c=$b; 
echo $b->abc;//这里输出ABC 
echo $c->abc;//这里输出ABC $b->abc="DEF"; 
echo $c->abc;//这里输出DEF
?>

在PHP5中,对象的复制是通过引用来实现的,如果想复制的话,可以使用__clone

取消引用

unset只会取消变量名和变量内容之间的联系,并不会销毁变量内容本身

<?php
$a = 1;
$b = &$a;
unset($b);
echo $a;//这里仍然会输出1,因为并没有销毁变量内容

考察题

<?php
    
    $data = ['a','b','c'];
    
    foreach ($data as $key => $value) {
        $value = &$data[$key];
    }

/**
 * 1、程序运行时,每一次循环结束后,变量$data的值是什么,请解释
 * 2、程序执行完成后,变量$data的值是什么?
 */

第一次进入循环:$data的第一个元素的keyvalue被赋值给$key$value,此时$key=0$value=a,执行$value = &$data[$key];时,$value指向$data[0];此时第一次循环结束,$data值没有发生变化,还是['a','b','c']
第二次进入循环:$data的第二个元素的keyvalue被赋值给$key$value,此时$key=1$value=b,而此时的$value指向的是$data[0]的地址,因此$data[0]的值也变成b,执行$value = &$data[$key];时,$value指向$data[1];此时第二次循环结束,$data的值为['b','b','c']
后面类推,第三次循环结束$data的值为['b','c','c']