PHP的引用详解
引用是什么
在PHP中引用意味着用不同的名字访问同一个变量内容。这并不像C的指针,替代的是,引用是符号表别名。注意在PHP中,变量名和变量内容是不一样的,因此同样的内容可以有不同的名字。最接近的比喻是Unix的文件名和文件本身——变量名是目录条目,而变量内容则是文件本身。引用可以被看作是Unix文件系统中的hardlink。
引用做什么
PHP的引用允许用两个变量来指向同一个内容。意思是,当这样做时:
<?php $a=&$b; ?>
这意味着$a和$b指向了同一个变量。
Note:
$a和$b在这里是完全相同的,这并不是$a指向了$b或者相反,而是$a和$b指向了同一个地方。
Note:
如果具有引用的数组被拷贝,其值不会解除引用。对于数组传值给函数也是如此。
Note:
如果对一个未定义的变量进行引用赋值、引用参数传递或引用返回,则会自动创建该变量。
Example#1对未定义的变量使用引用
<?php functionfoo(&$var){} foo($a);//$ais"created"andassignedtonull $b=array(); foo($b['b']); var_dump(array_key_exists('b',$b));//bool(true) $c=newStdClass; foo($c->d); var_dump(property_exists($c,'d'));//bool(true) ?>
同样的语法可以用在函数中,它返回引用,以及用在new运算符中(PHP4.0.4以及以后版本):
<?php $bar=&newfooclass(); $foo=&find_var($bar); ?>
自PHP5起,new自动返回引用,因此在此使用=&已经过时了并且会产生E_STRICT级别的消息。
Note:
不用&运算符导致对象生成了一个拷贝。如果在类中用$this,它将作用于该类当前的实例。没有用&的赋值将拷贝这个实例(例如对象)并且$this将作用于这个拷贝上,这并不总是想要的结果。由于性能和内存消耗的问题,通常只想工作在一个实例上面。
尽管可以用@运算符来抑制构造函数中的任何错误信息,例如用@new,但用&new语句时这不起效果。这是Zend引擎的一个限制并且会导致一个解析错误。
Warning
如果在一个函数内部给一个声明为global的变量赋于一个引用,该引用只在函数内部可见。可以通过使用$GLOBALS数组避免这一点。
Example#2在函数内引用全局变量
<?php $var1="Examplevariable"; $var2=""; functionglobal_references($use_globals) { global$var1,$var2; if(!$use_globals){ $var2=&$var1;//visibleonlyinsidethefunction }else{ $GLOBALS["var2"]=&$var1;//visiblealsoinglobalcontext } } global_references(false); echo"var2issetto'$var2'\n";//var2issetto'' global_references(true); echo"var2issetto'$var2'\n";//var2issetto'Examplevariable' ?>
把global$var;当成是$var=&$GLOBALS['var'];的简写。从而将其它引用赋给$var只改变了本地变量的引用。
Note:
如果在foreach语句中给一个具有引用的变量赋值,被引用的对象也被改变。
Example#3引用与foreach语句
<?php $ref=0; $row=&$ref; foreach(array(1,2,3)as$row){ //dosomething } echo$ref;//3-lastelementoftheiteratedarray ?>
引用做的第二件事是用引用传递变量。这是通过在函数内建立一个本地变量并且该变量在呼叫范围内引用了同一个内容来实现的。例如:
<?php functionfoo(&$var) { $var++; }
$a=5; foo($a); ?>