引用
先看一个面试题:
$a = 111;
$b = &$a; // 这里不是$b指向了$a,而是$a和$b指向了同一个地方
$a = 222;
var_dump($a);
var_dump($b);
1. 引用是什么?
在php中,引用意味着用不同的名字访问同一个变量内容。和C语言的指针不一样,因为不能做php的引用不能做指针运算,并不是实际的内存地址。
2. 引用传递
// 题目1
$a = 111;
$b = 222;
function foo(&$value)
{
$value = &$b;
}
foo($a);
var_dump($a);
// 题目2
$a = 111;
$b = 222;
function foo(&$value)
{
$value = 222;
}
foo($a);
var_dump($a);
php从5.4开始,已经丢弃了***foo(&$a)这种用法。只需要在函数声明的参数列表中加上***&符号已经可以起到引用的作用
3. 引用返回
面试题:
class foo {
public $value = 42;
public function &getValue() { // 方法定义加上&
return $this->value;
}
}
$obj = new foo;
$myValue = &$obj->getValue(); // $myValue 指向 $obj->value, which is 42.
$obj->value = 2;
echo $myValue; // 2
和参数传递不同,这里必须在两个地方都用*&*符号——指出返回的是一个引用,而不是通常的一个拷贝,同样也指出$myValue是作为引用的绑定,而不是通常的赋值。
4. 取消引用
当 unset 一个引用,只是断开了变量名和变量内容之间的绑定。这并不意味着变量内容被销毁了。
面试题:
$a = 1;
$b =& $a;
unset($a); // 其实是取消了变量名称$a和变量内容之间的引用,不影响$b和变量内容之间的引用。不会操作内存空间
var_dump($b);
来个比较难的题目
$data = ['a', 'b', 'c'];
foreach ($data as $k => $v) {
$v = &$data[$k];
}
var_dump($data);
面试题
请说明 php 中传值与传引用的区别。什么时候传值什么时候传引用?
答:
变量默认总是传值赋值 。那也就是说 ,当将一个表达式的值赋予一个变量时 ,整个原始 表达式的值被赋值到目标变量。这意味着,例如,当一个变量的值赋予另外一个变量时 ,改变其中一个变量的值,将不会影响到另外一个变量。
PHP 也提供了另外一种方式给变量赋值:引用赋值。这意味着新的变量简单的引用(换言之,“成为其别名” 或者 “指向”)了原始变量。改动新的变量将影响到原始变量 ,反之亦 然。使用引用赋值,简单地将一个 & 符号加到将要赋值的变量前(源变量)。
对象默认是传引用。
对于较大的数据,传引用比较好 ,这样可以节省内存的开销。