PHP中的引用详解

我们首先看下官方英文文档的解释。

PHP中的引用意味着你可以用不同的变量名访问同一个变量内容。在PHP中变量名和变量内容是不同的,引用是符号表别名。引用不同于C语言中的指针,你不能对其进行数学运算。最形象的比喻就是Unix的文件系统,变量名对应文件系统中的文件名,而变量内容对应文件系统中实际的文件内容,引用即为系统中的硬链接。

那么PHP中的引用和C语言中的指针有什么不同呢?C语言中加入定义一个整形指针“int *p”,我们可以对指针进行加操作“p++”,那么它就指向了下一个内存地址。或者我们进行赋值操作,给指针p一个新的地址“p = n”,那么p就指向了n所指向的地址,他们都指向同一个地址。而在PHP中我们不可以对引用使用加减操作,因为通过引用赋值时,如“$b=&$a”,新的$b只是一个变量名而已,和$a是一样的,&的作用就是使$b的变量内容指向了$a的变量内容,$b终究只是一个变量名,用官方的说法是$a的别名。说的直白点就是,使用了“&”的话就不会分配新的内存空间,引用的结果是新变量指向现有的内存空间

PHP中引用的作用是什么呢?引用有三个基本的作用:引用赋值、引用传递和引用返回。

引用赋值

对于“$a=$b”,$a和$b是完全一样的,他们都指向同一个内容。

引用传递

PHP中函数参数的传递都是值传递,都是将实参的值拷贝一份传递到函数中。如果想在函数中修改函数外部的值,那么就需要引用。

引用返回

可以使用引用进行函数返回,而不是返回值的拷贝。

具体的作用介绍可参考http://php.net/manual/en/language.references.whatdo.php

需要我们注意的是,在PHP5中的对象变量,我们需要深刻理解。PHP5中的对象变量已经不再保存整个对象的值,只是保存一个标识符来访问真正的对象内容。当对象作为参数传递,作为结果返回,或者赋值给另外一个变量,另外一个变量跟原来的不是引用的关系,只是他们都保存着同一个标识符的拷贝,这个标识符指向同一个对象的真正内容。 可以参考下列代码对本篇文章进行理解。

<?php

$a = 1;
$b = $a;
$b = 4;
echo $a . '<br>'; // 1

$b = &$a;
$b = 4;
echo $a . '<br>'; // 4
$c = $b;
$c = 5;
echo $b . '<br>'; // 4
echo $a . '<br><br>'; // 4

$a= 1;
function func (&$args){
    $args = 6;
}
func($a);
echo $a; // 6
?>

对象变量的引用

<?php
class A {
    public $foo = 'empty';
}
class B {
    public $foo = 'empty';
    public $bar = 'hello';
}

function normalAssignment($obj) {
    $obj->foo = 'changed';
    $obj = new B;
}

function referenceAssignment(&$obj) {
    $obj->foo = 'changed';
    $obj = new B;
}

$a = new A;
normalAssignment($a);
echo get_class($a), "\n";
echo "foo = {$a->foo}\n";

referenceAssignment($a);
echo get_class($a), "\n";
echo "foo = {$a->foo}\n";
echo "bar = {$a->bar}\n";

/*
prints:
A
foo = changed
B
foo = empty
bar = hello
*/
?>

代码中可以看出,普通变量的变量内容存储的就是实际的变量内容,而对象变量的变量内容实际上是对象的标志符,而不是正真的对象。例如将上述代码中的$a赋值给$b,“$b=$a”所代表的意义是创建一个新的变量$b,$b的变量内容存储的值和变量$a的变量内容所存储的值是一样的,都是对象的标识符,而且这两个变量具有不同的变量内容存储空间。而引用赋值“$b=$a”所代表的意义是变量$b的变量内容指向变量$a的变量内容,这两个变量的变量内容都指向一个存储空间。“=”和“=&”操作得到的变量都可对对象的值进行修改,若想在函数中修改对象的值,则在函数定义时可不必加“&”操作符。PHP5中对象的赋值操作不会产生新的对象,要复制对象,使用clone关键字。

发表评论

电子邮件地址不会被公开。 必填项已用*标注