• PHP 函数的“引用返回”概念释疑

    什么是引用返回
    服务器君一共花费 16.553 ms 进行了 2 次数据库查询,努力地为您提供了这个页面。
    广告很萌的

    很多时候我们会看到这样的代码(出自 CI 框架源码):

    $class =& load_class('a','b');
    

    我们都知道其中的'&'是指引用,但是它的作用是什么呢?它能够解决什么样的问题呢?带着这些问题,我们开始了解下“引用返回”。

    引用返回

    手册里是这么写的:引用返回用在当想用函数找到引用应该被绑定在哪一个变量上面时。不要用返回引用来增加性能,引擎足够聪明来自己进行优化。仅在有合理的技术原因时才返回引用!要返回引用,使用此语法:

    <?php
    class foo {
        public $value = 42;
    
        public function &getValue() {
            return $this->value;
        }
    }
    
    $obj = new foo;
    // $myValue is a reference to $obj->value, which is 42.
    // $myValue 是 $obj->value 的引用,它们的值都是 42
    $myValue = &$obj->getValue(); 
    // 对 $obj->value 重新复制,会影响到 $myValue 的值
    $obj->value = 2;
    // prints the new value of $obj->value, i.e. 2.
    echo $myValue; 	// 程序输出 2
    ?>
    

    本例中 getValue() 函数所返回的对象的属性将被赋值,而不是拷贝,就和没有用引用语法一样。

    参数传递不同,这里必须在两个地方都用 & 符号——指出返回的是一个引用,而不是通常的一个拷贝,同样也指出 $myValue 是作为引用的绑定,而不是通常的赋值。

    如果试图这样从函数返回引用:return ($this->value);,这将不会起作用,因为在试图返回一个表达式的结果而不是一个引用的变量。只能从函数返回引用变量——没别的方法。如果代码试图返回一个动态表达式或 new 运算符的结果,自 PHP 4.4.0 和 PHP 5.1.0 起会发出一条 E_NOTICE 错误。

    似懂非懂?那么我们来改写一下程序吧,让它变成一个常规的函数:

    <?php
    class foo {
        public $value = 42;
    
        public function getValue() {
            return $this->value;
        }
    }
    
    $obj = new foo;
    $myValue = $obj->getValue(); 
    $obj->value = 2;
    
    echo $obj->value;  // 程序输出 2
    echo $myValue; 	// 程序输出 42
    ?>
    

    现在能理解“引用返回用在当想用函数找到引用应该被绑定在哪一个变量上面时”这句话了吧,函数 &getValue() 把引用绑定在成员变量 $value 上了。正常来说,$obj = new foo; 产生的 $obj 是一个copy,它的成员变量 $value 与函数 getValue() 不存在“别名”(引用)关系。

    一些简单的例子

    看下面的简单例子,尝试去理解引用返回。

    <?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
    
    ?>
    

    程序运行结果:

    1
    2
    3
    6
    
    • 尽管函数声明方式是 function &test() 这样,但我们通过这种方式 $a = test() 的函数调用得到的其实不是函数的引用返回,这跟普通的函数调用没有区别。PHP 规定通过 $a = &test() 这种方式得到的才是函数的引用返回。

    用上面的例子来解释就是,$a = test() 这种方式调用函数,只是将函数的值赋给 $a 而已,而$a做任何改变都不会影响到函数中的$b。

    而通过 $a = &test() 方式调用函数呢,它的作用是将 return $b 中的 $b 变量的内存地址与 $a 变量的内存地址指向了同一个地方。即产生了相当于这样的效果 ($a=&$b), 所以改变 $a 的值也同时改变了 $b 的值。所以在执行了

    $a = &test();
    $a = 5;
    

    以后,$b的值变为了5。

    再来个程序例子加深理解:

    <?php
    /*
    ** 值传递和引用传递,值传递传递的是值的一个复本,引用传递传递的是值指向的内存地址
    */
    
    // 函数的引用,定义时也要加上 &
    function &func($a,$b){ 	
    	// 这里为了更直观看到效果,定义一个静态变量
    	static $result = 0;  	
    	$result+=$a+$b;
    	echo $result.'<br />';
    	return $result;
    }
     
    $a = $b = 10;
    
    // PHP里这样写函数的引用调用,和调用普通函数没有区别(只是将函数的返回值复制给$c这个变量,$c做任何改变不会影响上面函数中的$result)
    // 要记住:PHP里的函数引用定义及调用都要在函数名前加上 &
    $c = func($a,$b); 
    // 第一次执行func(),其静态变量$result的值变为 20(10+10)
    
    // 改变$c的值,不会对下面一行语句产生影响
    $c = 666;  
    // 第二次执行func(),其静态变量$result的值变为 40(20+10+10)
    $c = func($a,$b);
    
    echo '<hr />';
    
    // 这样才是PHP中引用函数的调用方式
    $d = &func($a,$b);  
    // 第三次执行func(),其静态变量$result的值变为 40(40+10+10)
    $d = 888;
    // 第四次执行func(),其静态变量$result的值变为 908(888+10+10)
    $d = func($a,$b);
    
    ?>
    
更多 推荐条目

Welcome to NowaMagic Academy!

现代魔法 推荐于 2013-02-27 10:23   

本章最新发布
随机专题
  1. [移动开发] 从代码角度去认识 Handler 4 个条目
  2. [PHP程序设计] fsockopen,curl与file_get_contents 12 个条目
  3. [数据库技术] MySQL常用自带函数 3 个条目
  4. [PHP程序设计] Nginx基本操作释疑 7 个条目
  5. [软件工程与项目管理] 开始了解Git 5 个条目
  6. [Python程序设计] Python语言概述 6 个条目
  7. [移动开发] 从代码角度去认识 Activity 4 个条目
  8. [数据库技术] SQL基础语法 1 个条目
  9. [移动开发] Android与SQLite数据库 7 个条目
  10. [Python程序设计] 标准库:urllib/urllib2 14 个条目
  11. [PHP程序设计] PHP中的Hash算法 3 个条目
  12. [Python程序设计] Python数据类型 11 个条目
窗口 -- [协会]