Golden Era's Blog

关于PHP的两种赋值方式

前言

PHP 有两种赋值方式,一种是传值赋值,一种是引用赋值。引用的意思简而概之就是不同变量使用同一个值,你可以理解为一个变量的“别名”。
两者的区别一句话概括之,传值赋值替换了变量指向,引用赋值改变了变量指向,下面以实际的例子来解释这句话。

引用传值赋值和传值赋值

一个传值赋值简单的例子

1
2
3
4
5
6
7
8
9
$var1 = 1;
$var2 = $var1;
$var1 = 2;
echo "$var2:", $var2;// 1
$var3 =& $var1;
$var3++;
echo "$var1:", $var1;// 3

上面的例子很好理解,$var2 复制了一份 $var1 的值,尽管后来 $var1 改变了,可 $var2 的值不会变化。$var3 =& $var1 这个语句表明了 $var3 和 $var1 指向了同一块区域,即 var3相当于 var1 的一个别名,改变了 $var3 的值时,$var1 的值同时也会变化。

一张图解释上段程序的赋值过程

函数中的两种赋值方式

两种传值方式的性质不同导致了在函数调用中的传值方式不一样,如果函数参数中变量名带 ‘&’ 符号的,即表明该参数是传值引用,仅需在函数定义处申明即可,不必在函数调用时申明。

1
2
3
4
5
6
7
8
9
10
11
12
$var1 = 1;
function foo(&$var2) {
$var2 =& $_SERVER['HTTP_HOST'];
}
function bar(&$var2) {
$var2 = 2;
}
echo "foo:", foo($var1); // 1
echo "bar:", bar($var1); // 2

为什么这里 $var1 的值没有像上面一样改变,请注意开篇提到的,引用表示变量的别名,符号&即表明了改变了该变量的指向,$var2 =& $_SERVER['HTTP_HOST']表示 $_SERVER['HTTP_HOST'] 有了另一个别名$var2,解除了和$var1的别名关系,变量$var2的值指向了$_SERVER['HTTP_HOST']。当调用函数bar时,就和我们之前设想的一样。

一张图解释上面赋值过程:

函数的引用返回

PHP 提供了一种返回函数变量引用值的方法,在函数名称前加符号&来表示返回返回值的引用,参见例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function &func(){
static $var = 1;
$var++;
return $var;
}
$var1 =& func();
$var2 = func();
echo "var1:", $var1; // 4
echo "var2:", $var2; // 3
$var1++;
func();
echo "var1:", $var1; // 5
echo "var2:", $var2; // 3

首先关于静态变量的使用请参考使用静态变量,变量 $var 的作用域仍为在 func() 内部,和普通变量唯一的区别就在函数调用完毕后 $var 变量并不会被销毁,而会继续存在。
一张图解释上面赋值过程

总结

PHP 中的引用和 C 语言中的指针可谓天壤之别,一个是变量别名,一个是变量内存地址。相比起来,PHP 的引用可要简单了不少,只要牢记开篇提起的,引用是改变了变量的指向,相信对于 PHP 的变量引用就没有什么问题了。下一篇讲讲对象引用的问题。

参考

  1. What References Are
  2. What References Are Not
  3. Returning References
  4. 5个php实例,细致说明传值与传引用的区别
  5. 使用静态变量