《PHP实例:深入分析PHP引用(&)》要点:
本文介绍了PHP实例:深入分析PHP引用(&),希望对您有用。如果有疑问,可以联系我们。
引用是什么
在 PHP 中引用意味着用不同的名字拜访同一个变量内容.这并不像 C 的指针,替代的是,引用是符号表别名.注意在 PHP 中,变量名和变量内容是不一样的,因此同样的内容可以有不同的名字.最接近的比喻是 Unix 的文件名和文件本身――变量名是目录条目,而变量内容则是文件本身.引用可以被看作是 Unix 文件系统中的 hardlink.PHP应用
引用做什么
PHP 的引用允许用两个变量来指向同一个内容.意思是,当这样做时:PHP利用
<?php $a =& $b; ?>
这意味着 $a 和 $b 指向了同一个变量.PHP利用
Note:PHP利用
$a 和 $b 在这里是完全相同的,这并不是 $a 指向了 $b 或者相反,而是 $a 和 $b 指向了同一个处所.PHP应用
Note:PHP利用
如果具有引用的数组被拷贝,其值不会解除引用.对付数组传值给函数也是如此.PHP应用
Note:PHP利用
如果对一个未定义的变量进行引用赋值、引用参数传递或引用返回,则会自动创立该变量.PHP应用
Example #1 对未界说的变量使用引用PHP应用
<?php function foo(&$var) { } foo($a); // $a is "created" and assigned to null $b = array(); foo($b['b']); var_dump(array_key_exists('b', $b)); // bool(true) $c = new StdClass; foo($c->d); var_dump(property_exists($c, 'd')); // bool(true) ?>
同样的语法可以用在函数中,它返回引用,以及用在 new 运算符中(PHP 4.0.4 以及以后版本):
PHP利用
<?php $bar =& new fooclass(); $foo =& find_var($bar); ?>
自 PHP 5 起,new 自动返回引用,因此在此使用 =& 已经过时了并且会产生 E_STRICT 级其余消息.PHP应用
Note:PHP利用
不用 & 运算符导致对象生成了一个拷贝.如果在类中用 $this,它将作用于该类当前的实例.没有用 & 的赋值将拷贝这个实例(例如对象)而且 $this 将作用于这个拷贝上,这并不总是想要的结果.由于性能和内存消耗的问题,通常只想工作在一个实例上面.PHP应用
尽管可以用 @ 运算符来抑制构造函数中的任何错误信息,例如用 @new,但用 &new 语句时这不起效果.这是 Zend 引擎的一个限制而且会导致一个解析错误.PHP应用
WarningPHP利用
如果在一个函数内部给一个声明为 global 的变量赋于一个引用,该引用只在函数内部可见.可以通过使用 $GLOBALS 数组避免这一点.PHP利用
Example #2 在函数内引用全局变量PHP利用
<?php $var1 = "Example variable"; $var2 = ""; function global_references($use_globals) { global $var1, $var2; if (!$use_globals) { $var2 =& $var1; // visible only inside the function } else { $GLOBALS["var2"] =& $var1; // visible also in global context } } global_references(false); echo "var2 is set to '$var2'\n"; // var2 is set to '' global_references(true); echo "var2 is set to '$var2'\n"; // var2 is set to 'Example variable' ?>
把 global $var; 当成是 $var =& $GLOBALS['var']; 的简写.从而将其它引用赋给 $var 只改变了当地变量的引用.
Note:PHP应用
如果在 foreach 语句中给一个具有引用的变量赋值,被引用的对象也被转变.PHP应用
Example #3 引用与 foreach 语句PHP利用
<?php $ref = 0; $row =& $ref; foreach (array(1, 2, 3) as $row) { // do something } echo $ref; // 3 - last element of the iterated array ?>
引用做的第二件事是用引用传递变量.这是通过在函数内建立一个当地变量并且该变量在呼叫范围内引用了同一个内容来实现的.例如:PHP应用
<?php function foo(&$var) { $var++; } $a=5; foo($a); ?>
将使 $a 酿成 6.这是因为在 foo 函数中变量 $var 指向了和 $a 指向的同一个内容.更多详细解释见引用传递.PHP应用
引用做的第三件事是引用返回.PHP利用
引用不是什么
如前所述,引用不是指针.这意味着下面的布局不会产生预期的效果:PHP应用
<?php function foo(&$var) { $var =& $GLOBALS["baz"]; } foo($bar); ?>
这将使 foo 函数中的 $var 变量在函数调用时和 $bar 绑定在一起,但接着又被重新绑定到了 $GLOBALS["baz"] 上面.不可能通过引用机制将 $bar 在函数调用范围内绑定到别的变量上面,因为在函数 foo 中并没有变量$bar(它被表现为 $var,但是 $var 只有变量内容而没有调用符号表中的名字到值的绑定).可以使用引用返回来引用被函数选择的变量.PHP应用
引用传递
可以将一个变量通过引用传递给函数,这样该函数就可以改动其参数的值.语法如下:PHP应用
<?php function foo(&$var) { $var++; } $a=5; foo($a); // $a is 6 here ?>
注意在函数调用时没有引用符号――只有函数定义中有.光是函数定义就足够使参数通过引用来正确传递了.在最近版本的 PHP 中如果把 & 用在 foo(&$a); 中会获得一条警告说“Call-time pass-by-reference”已经过时了.PHP应用
以下内容可以通过引用传递:PHP利用
变量,例如 foo($a)
New 语句,例如 foo(new foobar())
从函数中返回的引用,例如:PHP利用
<?php function &bar() { $a = 5; return $a; } foo(bar()); ?>
详细解释见引用返回.
任何其它表达式都不克不及通过引用传递,结果未定义.例如下面引用传递的例子是无效的:PHP应用
<?php function bar() // Note the missing & { $a = 5; return $a; } foo(bar()); // 自 PHP 5.0.5 起导致致命差错 foo($a = 5) // 表达式,不是变量 foo(5) // 导致致命差错 ?>
这些条件是 PHP 4.0.4 以及以后版本有的.PHP应用
引用返回
引用返回用在当想用函数找到引用应该被绑定在哪一个变量上面时.不要用返回引用来增加性能,引擎足够聪明来本身进行优化.仅在有合理的技术原因时才返回引用!要返回引用,使用此语法:PHP应用
<?php class foo { public $value = 42; public function &getValue() { return $this->value; } } $obj = new foo; $myValue = &$obj->getValue(); // $myValue is a reference to $obj->value, which is 42. $obj->value = 2; echo $myValue; // prints the new value of $obj->value, i.e. 2. ?>
本例中 getValue 函数所返回的工具的属性将被赋值,而不是拷贝,就和没有用引用语法一样.PHP应用
Note: 和参数传递不同,这里必需在两个地方都用 & 符号――指出返回的是一个引用,而不是通常的一个拷贝,同样也指出 $myValue 是作为引用的绑定,而不是通常的赋值.PHP应用
Note: 如果试图这样从函数返回引用:return ($this->value);,这将不会起作用,因为在试图返回一个表达式的结果而不是一个引用的变量.只能从函数返回引用变量――没别的办法.如果代码试图返回一个动态表达式或 new 运算符的结果,自 PHP 4.4.0 和 PHP 5.1.0 起会发出一条 E_NOTICE 错误.PHP应用
<?php function &test(){ static $b=0;//申明一个静态变量 $b=$b+1; echo $b; return $b; } $a=test();//这条语句会输出$b的值为1 $a=5; $a=test();//这条语句会输出$b的值为2 $a=&test();//这条语句会输出$b的值为3 $a=5; $a=test();//这条语句会输出$b的值为6 ?>
$a=test()方式调用函数,只是将函数的值赋给$a罢了,而$a做任何改变化,都不会影响到函数中的$b,而通过$a=&test()方式调用函数呢, 他的作用是将return $b中的$b变量的内存地址与$a变量的内存地址指向了同一个地方,即产生了相当于这样的效果($a=&b;) 所以改变$a的值,也同时改变了$b的值,所以在执行了 $a=&test(); $a=5; 以后,$b的值变为了5.PHP应用
撤消引用
当 unset 一个引用,只是断开了变量名和变量内容之间的绑定.这并不意味着变量内容被销毁了.例如:PHP应用
<?php $a = 1; $b =& $a; unset($a); ?>
不会 unset $b,只是 $a.PHP利用
再拿这个和 Unix 的 unlink 挪用来类比一下可能有助于理解.PHP应用
引用定位
许多 PHP 的语法布局是通过引用机制实现的,所以上述有关引用绑定的一切也都适用于这些布局.一些布局,例如引用传递和返回,已经在上面提到了.其它使用引用的布局有:PHP应用
global 引用
当用 global $var 声明一个变量时实际上建立了一个到全局变量的引用.也便是说和这样做是相同的:PHP应用
<?php $var =& $GLOBALS["var"]; ?>
这意味着,例如,unset $var 不会 unset 全局变量.PHP利用
使用unset($a)与$a=null的结果是纷歧样的.如果该块内存只有$a一个映射,那么unset($a)与$a=null等价,该内存的引用计数变为0,被自动回收;如果该块内存有$a和$b两个映射,那么unset($a)将导致$a=null且$b不变的情况,而$a=null会导致$a=$b=null的情况.PHP应用
原因:某变量赋值为null,将导致该变量对应的内存块的引用计数直接置为0,被自动收受接管.PHP应用
$this
在一个对象的办法中,$this 永远是调用它的对象的引用.PHP应用
引用的作用
如果程序比拟大,引用同一个对象的变量比拟多,并且希望用完该对象后手工清除它,个人建议用 "&" 方式,然后用$var=null的方式清除. 其它时候还是用php5的默认方式吧. 另外, php5中对于大数组的传递,建议用 "&" 方式, 毕竟节省内存空间使用.PHP应用
下面再来个小插曲 php中对于地址的指向(类似指针)功能不是由用户本身来实现的,是由Zend核心实现的,php中引用采用的是“写时拷贝”的原理,就是除非发生写操作,指向同一个地址的变量或者对象是不会被拷贝的.PHP应用
通俗的讲PHP利用
1:如果有下面的代码PHP利用
<?ph $a="ABC"; $b=$a; ?>
其实此时,$a与$b都是指向同一内存地址,而并不是$a与$b占用分歧的内存.PHP应用
2:如果在上面的代码根基上再加上如下代码PHP应用
$a="EFG";
由于$a与$b所指向的内存的数据要重新写一次了,此时Zend核心会自动断定 自动为$b生产一个$a的数据拷贝,重新申请一块内存进行存储.PHP应用
PHP利用
维易PHP培训学院每天发布《PHP实例:深入分析PHP引用(&)》等实战技能,PHP、MYSQL、LINUX、APP、JS,CSS全面培养人才。