我在看框架内的class MST_DBC 时,该类中的一个final static public function & connect($remote = null) 方法 引起了我的好奇!因为读了下这方法的代码,它最终是:
self::$_register[$remote] = new $adapterClass($config); return self::$_register[$remote];
看上去是返回了数组return self::$_register[$remote];值,但是看它上面这数组的赋值是一个new 出来的对象。这里就引起兴趣的地方。
我查了相关资料,并实践了一下:
<?php class A { public $str = 'Hello'; public $arr = array(1,2,3); public function & arr(){ return $this->arr; } public function & str(){ return $this->str; } } $a = new A(); $str = & $a->str(); $str = 'World'; echo $a->str; //输出World $arr = & $a->arr(); array_pop($arr); print_r($a->arr()); //输出Array ( [0] => 1 [1] => 2 )
由输出的结果得出类方法中方法名前用到&符号就是传递引用,包括在赋值时也要在前面加上&,就如用变量时的情况一样($a = & $b)。
我们继续看下面一种情况:
<?php class A { private $str = 'Hello'; public function & getStr(){ return $this->str; } } $a = new A(); $str = & $a->getStr(); $str = 'World'; echo $a->getStr(); //输出World
上面代码,一样用到了类方法传递引用,但注意类中的私有属性给外面变量给修改了!(我们当然可以在类中加个方法来设置私有属性值)
我们继续看这返回对象时的情况(如同框架中的MBC类的&connect方法):
<?php class A { public $obj = ''; public function & getObj(){ $this->obj = new B(); return $this->obj; } } class B { public $bb = 'isBB'; } $a = new A(); $b = & $a->getObj(); echo $b->bb; //输出isBB
下面再给出代码,跟上面的用法一样:但是我们在下面代码中去掉类方法中&符号,
<?php class A { public $obj = ''; public function getObj(){ $this->obj = new B(); return $this->obj; } } class B { public $bb = 'isBB'; } $a = new A(); $b = $a->getObj(); echo $b->bb; //输出isBB
如你所见,输出的结果是一样的。
由此:我总结出PHP5中当类方法用到&返回引用时有两点要注意,其一:要注意返回私有化属性时,是能被外部修改。其二:值类型的类型(如string int)包括数组array 可能达到你传递引用的目的,而当是对象object时,因为赋值时对象本身返回的是引用。如同下面情况:
<?php class A { public $obj = 'aa'; } $a = new A(); $b = $a; $b->obj = 'bb'; echo $a->obj; //输出bb
提示:所以去掉框架上DBC类的& connect()方法中的&是没有任何问题的,大师你认为呢?
附上PHP5.2和PHP5.3:
PHP5.2 (有&和无时结果一致)
PHP5.3 (有&和无时结果一致)
我想说,请你贴上PHP5.2/PHP5.3/PHP5.4的测试结果。
PHP每个小版本都有微小的差别……
就跑在你自己的本来PHP5.4反应不了任何问题……
已测其他版本,印象中从PHP5开始已经是这特性