php引用允许两个变量指向同一个内容。意思是,当这样做时
<?php
$a=&$b;
?>
意味着$a与$b指向同一变量,这并不是$a指向了$b或者相反,而是$a和$b指向了同一地方如果对一个未定义的变量进行引用赋值、引用参数传递或引用返回,则会自动创建给变量
例子:
<?php
function foo(&$var){
}
var_dump(foo($a));//null引用赋值
$b=array();
foo($b['b']);
var_dump(array_key_exists('b',$b));//bool(true) 引用参数传递
?>
引用可以用在函数中。它返回引用,以及用在new运算符中
<?php
$foo=& myFunction($bar);
?>
注意:
如果在一个函数内部给一个声明为 global 的变量赋于一个引用,该引用只在函数内部可见。可以通过使用 $GLOBALS 数组避免
例子:
<?php
$var1='hello';
$var2='';
function global_reference($globals){
global $var1,$var2;
if(!$globals){
$var2=& $var1;
}else{
$GLOBALS['var2']=& $var1;
}
}
//global_reference(false);
//echo "var2 is set to ".$var2;//var2 is set to global关键字只在函数内部全局
global_reference(true);
echo "var2 is set to".$var2;//var2 is set tohello $GLOBALS 变量全局使用
?>
如果在 foreach 语句中给一个具有引用的变量赋值,被引用的对象也被改变
<?php
$ref=0;
$row=& $ref;
foreach(array(1,2) as $row){
}
echo $ref;//2
?>
引用做的第二件事是:引用传递变量
可以将一个变量通过引用传递给函数,这样该函数就可以修改其参数的值<?
function foo(&$var){
$var++;
}
$a=4;
foo($a);
echo $a;//5
?>
注意在函数调用时没有引用符号——只有函数定义中有。光是函数定义就足够使参数通过引用来正确传递了
- 变量 例如上例 foo($a)
- new语句 例如 foo(new foobar())
- 从函数中返回的引用
任何其它表达式都不能通过引用传递,结果未定义
应用做的第三件事:引用返回
引用返回用在当想用函数找到引用应该被绑定在哪一个变量上面时。不要用返回引用来增加性能,引擎足够聪明来自己进行优化。仅在有合理的技术原因时才返回引用!要返回引用,使用此语法:
例子:
<?php
class foo{
public $value=42;
public function &getValue(){
return $this->value;
}
}
$a=new foo();
$myvalue=& $a->getValue();
$a->value=2;
echo $myvalue;//2
?>
和参数传递不同,这里必须在两个地方都用 & 符号——指出返回的是一个引用,而不是通常的一个拷贝,同样也指出 $myValue 是作为引用的绑定,而不是通常的赋值。
例子分析:
<?php
class foo{
protected $name;
function __construct($str){
$this->name=$str;
}
function __tostring(){
return 'my name shi:'.$this->name.' and I live in:'.__class__;
}
function setName($str){
$this->name=$str;
}
}
class MasterOne{
protected $foo;
function __construct($f){
$this->foo=$f;
}
function __toString(){
return 'Master:'.__class__.' |foo:'.$this->foo;
}
function setFooName($str){
$this->foo->setName($str);
}
}
class MasterTwo{
protected $foo;
function __construct($f){
$this->foo=$f;
}
function __toString(){
return 'Master:'.__class__.' |foo:'.$this->foo;
}
function setFooName($str){
$this->foo->setName($str);
}
}
$bar = new foo('bar');
print("\n");
print("Only Created \$bar and printing \$bar\n");
print( $bar ); //my name shi:bar and I live in:foo
print("\n");
print("Now \$baz is referenced to \$bar and printing \$bar and \$baz\n");
$baz =& $bar;
print( $bar ); //my name shi:bar and I live in:foo
print("\n");
print("Now Creating MasterOne and Two and passing \$bar to both constructors\n");
$m1 = new MasterOne( $bar );
$m2 = new MasterTwo( $bar );
print( $m1 ); //Master:MasterOne |foo:my name shi:bar and I live in:foo
print( $m2 ); //Master:MasterTwo |foo:my name shi:bar and I live in:foo
print("\n");
print("Now changing value of \$bar and printing \$bar and \$baz\n");
$bar->setName('baz');
print( $bar ); //my name shi:baz and I live in:foo
print( $baz ); //my name shi:baz and I live in:foo
print("\n");
print("Now printing again MasterOne and Two\n");
print( $m1 ); //Master:MasterOne |foo:my name shi:baz and I live in:foo
print( $m2 ); //Master:MasterTwo |foo:my name shi:baz and I live in:foo
print("\n");
print("Now changing MasterTwo's foo name and printing again MasterOne and Two\n");
$m2->setFooName( 'MasterTwo\'s Foo' );
print( $m1 ); //Master:MasterOne |foo:my name shi:MasterTwo's Foo and I live in:foo
print( $m2 ); //Master:MasterTwo |foo:my name shi:MasterTwo's Foo and I live in:fooAlso
print("Also printing \$bar and \$baz\n");
print( $bar ); //my name shi:MasterTwo's Foo and I live in:foo
print( $baz ); //my name shi:MasterTwo's Foo and I live in:foo
?>