众所周知在PHP中,引用的使用方式有三种,分别是:引用赋值 $a = &$b
、引用传递 fn(&$a)
、引用返回 function &$a()
,前两种在PHP代码中很常见就不举栗子了,这里单独来讲讲引用返回
通过官方文档我们了解到,这是一种可以用来引用数组/对象内部元素的方式,具体demo如下:
function &get(&$data, $key)
{
foreach (explode('.', $key) as $k) {
if (isset($data[$k])) {
$data = &$data[$k];
}
}
return $data;
}
$data = ['a' => ['b' => ['c' => ['d' => 'lying']]]];
$val = &get($data, 'a.b.c');
$val['test'] = 'test';
var_dump($val, $data);
这里$val
就是引用的$data
内部多层嵌套下的c元素,改变$val
的值就会改变$data['a']['b']['c']
的值。如果想要取消引用,直接 unset 掉原引用的变量即可,因为这样只是断开了变量名和变量内容之间的绑定。这并不意味着变量内容被销毁了。
不过官方文档还说过:
引用返回用在当想用函数找到引用应该被绑定在哪一个变量上面时。 不要用返回引用来增加性能,引擎足够聪明来自己进行优化。 仅在有合理的技术原因时才返回引用!
通过这段话我们得知,其实返回 References 并不会提高性能,有时候反而降低性能,所以不要想当然的使用这个特性来“优化”程序。但我们可以了解一下这种用法,毕竟这也是返回值的一种使用方式。
ps:在一个对象的方法中,$this
永远是调用它的对象的引用。
当然引用更多是用在 foreach 迭代数组的情况,比如说:
$a = [['id' => 1, 'name' => 'test'], ['id' => 2, 'name' => 'fantasticbin']];
foreach ($a as &$v) {
$v['age'] = 18;
}
var_dump($a);
这里可直接用引用来操作子元素,性能比通过 key 来调用元素更好。但是这种使用方式会有一个问题,那就是 foreach 结束后$v
变量没有被释放掉,而是一直引用着迭代数组的最后一个元素,如果在后续的逻辑中再次操作$v
,就会直接影响迭代数组的结果,比如在 foreach 后和 var_dump 之前增加这段:
$v = 'test';
我们可以看到id为2的这个子元素已经被改成了字符串test,这不是我们想要的结果。那如何避免发生这种情况呢?一方面可以在后续的代码中避免再使用$v
,另一方面我们可以在foreach迭代数组后立即unset($v)
就可以了。