很多时候我们会看到这样的代码(出自 CI 框架源码):
1 |
$class =& load_class('a','b'); |
我们都知道其中的'&'是指引用,但是它的作用是什么呢?它能够解决什么样的问题呢?带着这些问题,我们开始了解下“引用返回”。
引用返回
手册里是这么写的:引用返回用在当想用函数找到引用应该被绑定在哪一个变量上面时。不要用返回引用来增加性能,引擎足够聪明来自己进行优化。仅在有合理的技术原因时才返回引用!要返回引用,使用此语法:
05 |
public function &getValue() { |
11 |
// $myValue is a reference to $obj->value, which is 42. |
12 |
// $myValue 是 $obj->value 的引用,它们的值都是 42 |
13 |
$myValue = &$obj->getValue(); |
14 |
// 对 $obj->value 重新复制,会影响到 $myValue 的值 |
16 |
// prints the new value of $obj->value, i.e. 2. |
17 |
echo $myValue; // 程序输出 2 |
本例中 getValue() 函数所返回的对象的属性将被赋值,而不是拷贝,就和没有用引用语法一样。
和参数传递不同,这里必须在两个地方都用 & 符号——指出返回的是一个引用,而不是通常的一个拷贝,同样也指出 $myValue 是作为引用的绑定,而不是通常的赋值。
如果试图这样从函数返回引用:return ($this->value);,这将不会起作用,因为在试图返回一个表达式的结果而不是一个引用的变量。只能从函数返回引用变量——没别的方法。如果代码试图返回一个动态表达式或 new 运算符的结果,自 PHP 4.4.0 和 PHP 5.1.0 起会发出一条 E_NOTICE 错误。
似懂非懂?那么我们来改写一下程序吧,让它变成一个常规的函数:
05 |
public function getValue() { |
11 |
$myValue = $obj->getValue(); |
14 |
echo $obj->value; // 程序输出 2 |
15 |
echo $myValue; // 程序输出 42 |
现在能理解“引用返回用在当想用函数找到引用应该被绑定在哪一个变量上面时”这句话了吧,函数 &getValue() 把引用绑定在成员变量 $value 上了。正常来说,$obj = new foo; 产生的 $obj 是一个copy,它的成员变量 $value 与函数 getValue() 不存在“别名”(引用)关系。
一些简单的例子
看下面的简单例子,尝试去理解引用返回。
13 |
$a = test(); //这条语句会输出 $b 的值为 1 |
16 |
$a = test(); //这条语句会输出 $b 的值为2 |
18 |
$a = &test(); //这条语句会输出 $b 的值为3 |
21 |
$a = test(); //这条语句会输出 $b的值 为6 |
程序运行结果:
用上面的例子来解释就是,$a = test() 这种方式调用函数,只是将函数的值赋给 $a 而已,而$a做任何改变都不会影响到函数中的$b。
而通过 $a = &test() 方式调用函数呢,它的作用是将 return $b 中的 $b 变量的内存地址与 $a 变量的内存地址指向了同一个地方。即产生了相当于这样的效果 ($a=&$b), 所以改变 $a 的值也同时改变了 $b 的值。所以在执行了
以后,$b的值变为了5。
再来个程序例子加深理解:
03 |
** 值传递和引用传递,值传递传递的是值的一个复本,引用传递传递的是值指向的内存地址 |
07 |
function &func($a,$b){ |
08 |
// 这里为了更直观看到效果,定义一个静态变量 |
11 |
echo $result.'<br />'; |
17 |
// PHP里这样写函数的引用调用,和调用普通函数没有区别(只是将函数的返回值复制给$c这个变量,$c做任何改变不会影响上面函数中的$result) |
18 |
// 要记住:PHP里的函数引用定义及调用都要在函数名前加上 & |
20 |
// 第一次执行func(),其静态变量$result的值变为 20(10+10) |
22 |
// 改变$c的值,不会对下面一行语句产生影响 |
24 |
// 第二次执行func(),其静态变量$result的值变为 40(20+10+10) |
31 |
// 第三次执行func(),其静态变量$result的值变为 40(40+10+10) |
33 |
// 第四次执行func(),其静态变量$result的值变为 908(888+10+10) |
- PHP引用(&)初探:函数的引用返回
函数的引用返回 先看代码: <?php function &test() { static $b=0;//申明一个静态变量 $b=$b+1; echo $b; return $b; } ...
- php函数名前添加& 函数的引用返回
function &test(){ static $b=0; $b= $b+1; return $b; } $a= test(); echo $a,"\n"; $a = 3 ...
- php函数的引用返回
<?php function &test(){ static $b = 1; $b += 2; return $b; } $a = &test(); $a =8; $c = te ...
- 详解php中函数的引用传递和返回 (附代码)
本篇文章带大家了解一下php的引用,详细介绍一下函数的引用传递和引用返回.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助.php的引用(就是在变量或者函数.对象等前面加上&符号 ...
- php变量的引用及函数的引用
Php变量的引用及函数的引用放回 变量的引用 $a="ABC"; $b =&$a; echo $a;//这里输出:ABC echo $b;//这里输 ...
- php引用(&)详解及注意事项——引用返回function &a();&a()
http://www.cnblogs.com/xiaochaohuashengmi/archive/2011/09/10/2173092.html 函数的引用返回 先看代码 <?php func ...
- 常量函数、常量引用参数、常量引用返回值[C++]
1. 关于常量引用正像在C语言中使用指针一样,C++中通常使用引用 有一个函数... foo()并且这个函数返回一个引用...... & foo()...., 一个指向位图(Bitmap)的引 ...
- [二] java8 函数式接口详解 函数接口详解 lambda表达式 匿名函数 方法引用使用含义 函数式接口实例 如何定义函数式接口
函数式接口详细定义 package java.lang; import java.lang.annotation.*; /** * An informative annotation type use ...
- C++命名空间、函数重载、缺省参数、内联函数、引用
一 .C++入门 1.C++关键字 2.命名空间 3.C++输入&输出 4.缺省参数 5.函数重载 6.引用 7.内联函数 8.auto关键字 9.基于范围的for循环 10.指针空值null ...
随机推荐
- 在CentOS 6.3中安装与配置JDK-7
在CentOS 6.3中安装与配置JDK-7 来源:互联网 作者:佚名 时间:02-07 16:28:33 [大 中 小] 在CentOS-6.3中安装与配置JDK-7,有需要的朋友可以参考下 安装说 ...
- Oracle数据库之PL/SQL包
Oracle数据库之PL/SQL包 1. 简介 包(PACKAGE)是一种数据对象,它是一组相关过程.函数.变量.常量和游标等PL/SQL程序设计元素的组合,作为一个完整的单元存储在数据库中,用名称来 ...
- java.io.serializable
为什么要实现 java.io.serializable? 简单点:“好处就是将来项目如果要做集群的话,就实现java.io.serializable接口”
- dede操作成功信息提示修改
函数修改 include/common.func.php 文件 function ShowMsg()函数
- ecshop数据库操作类
ECShop v2.7.2没有使用一些开源的数据库操作类,比如adodb或者PEAR,而是封装了自己的实现. 好处:实现非常轻量,只有一个文件,27Kb,大大减小了分发包的文件大小. 当网站需要做me ...
- A题 - A + B Problem
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Description Cal ...
- hadoop 异常 INFO ipc.Client: Retrying connect to server:
// :: INFO ipc.Client: Retrying connect to server: master/. Already tried , sleepTime= SECONDS) // : ...
- 开源java
http://code.google.com/p/nullpomino/source/checkout http://www.open-open.com/open254058.htm http://w ...
- ECMAScript 6 模块简介
任何平台的其中一个重要特性,除了需要支持代码库外就是模块.直到现在,Javascript还不支持原生的模块化.结果是,各种解决方案都将模块添加到类库中,比如CommonJS modules(部分由no ...
- 一篇故事讲述了计算机网络里的基本概念:网关,DHCP,IP寻址,ARP欺骗,路由,DDOS等...
计算机主机网关的作用是什么? 假设你的名字叫小不点,你住在一个大院子里,你的邻居有很多小伙伴,在门口传达室还有个看大门的李大爷,李大爷就是你的网关.当你想跟院子里的某个小伙伴玩,只要你在院子里大喊一声 ...