摘自:http://php.net/manual/en/language.oop5.references.php
通过上面的这段描述,我们可以知道以下几个关键点:
- 从php 5 开始,一个对象变了不再保存对象自己本身,而是保存的an object identifier,类比于指针。通过object identifier可以访问到实际的对象。并且在对象的参数传递、返回值、赋值中,接收这些操作的变量得到的是object identifier,而不是引用(或者说别名)。
- a php reference 是别名,类似于linux的软连接。
也就是说正常情况下,对象的传递是传递的object identifier。而在加了&标志时,传递的才是引用(或者说是别名)。
进一步理解,引用和object identifier有什么区别分?
构造类如下:
1 a=$a; 7 $this->b=$b; 8 } 9 public function printContent(){10 echo "a=$this->a b=$this->b\n";11 }12 }
进行如下操作:
1 $aa = new A(1,2); 2 $bb = $aa; //传递的是object identifier 3 $cc = &$aa; //$cc是对象aa的别名 4 $aa = new A(55,1); 5 echo '打印对象aa的内容'."\n"; 6 $aa->printContent(); //a=55 b=1 7 echo '打印对象bb的内容'."\n"; 8 $bb->printContent(); //a=1 b=2 9 echo '打印对象cc的内容'."\n";10 $cc->printContent(); //a=55 b=1
由上面的输出可知,当$aa的指向的内容发生变化时,因为$cc是$aa的别名,所以跟随变化。而$bb只是保存了在执行第二行语句时和$aa相同的object identifier,在执行第四行语句后,$aa保存的object identifier变成了新的对象A(55,1)的identifier,所以$bb不受影响。
进一步,查看参数传递过程中引用和identifier的差异:
定义以下两个方法:
1 function change($tmp){2 $tmp = new A(2,3);3 return $tmp;4 }5 function changeByRef(&$tmp){6 $tmp = new A(4,5);7 return $tmp;8 }
执行如下操作:
1 $aa = new A(1,2); 2 echo '初始化时打印对象aa'."\n"; 3 $aa->printContent(); //a=1 b=2 4 5 $bb = change($aa); 6 echo '调用change方法后打印对象aa'."\n"; 7 $aa->printContent(); //a=1 b=2 8 echo '调用change方法后打印返回的对象bb'."\n"; 9 $bb->printContent(); //a=2 b=310 11 12 $bb = changeByRef($aa);13 echo '调用changeByRef方法后打印对象aa'."\n";14 $aa->printContent(); //a=4 b=515 echo '调用change方法后打印返回的对象bb'."\n";16 $bb->printContent(); //a=4 b=5
可见,当传递的是object identifier时,改变方法的参数的object identifier不会影响到被传递的对象(即$aa)。而传递的是别名时则会影响到。
需要注意的是:不论传递的是对象的object identifier或则引用,当在方法中修改对象的属性时,因为实际上修改地是相同的object,因此会影响到被传递的对象或者被引用的对象。
更多的对象与引用的实例说明可以参考以下代码:
摘自:http://php.net/manual/en/language.oop5.references.php