对象复制
在多数情况下,我们并不需要完全复制一个对象来获得其中属性。但有一个情况下确实需要:如果你有一个 GTK 窗口对象,该对象持有窗口相关的资源。你可能会想复制一个新的窗口,保持所有属性与原来的窗口相同,但必须是一个新的对象(因为如果不是新的对象,那么一个窗口中的改变就会影响到另一个窗口)。还有一种情况:如果对象 A 中保存着对象 B 的引用,当你复制对象 A 时,你想其中使用的对象不再是对象 B 而是 B 的一个副本,那么你必须得到对象 A 的一个副本。
对象复制可以通过 clone 关键字来完成(如果可能,这将调用对象的 __clone() 方法)。对象中的 __clone() 方法不能被直接调用。
$copy_of_object = clone $object;
当对象被复制后,PHP 5 会对对象的所有属性执行一个浅复制(shallow copy)。所有的引用属性 仍然会是一个指向原来的变量的引用。
void __clone ( void )
当复制完成时,如果定义了 __clone()方法,则新创建的对象(复制生成的对象)中的 __clone()方法会被调用,可用于修改属性的值(如果有必要的话)。
- <?php
- class SubObject
- {
- static $instances = 0 ;
- public $instance ;
- public function __construct () {
- $this -> instance = ++ self :: $instances ;
- }
- public function __clone () {
- $this -> instance = ++ self :: $instances ;
- }
- }
- class MyCloneable
- {
- public $object1 ;
- public $object2 ;
- function __clone ()
- {
- // 强制复制一份this->object, 否则仍然指向同一个对象
- $this -> object1 = clone $this -> object1 ;
- }
- }
- $obj = new MyCloneable ();
- $obj -> object1 = new SubObject ();
- $obj -> object2 = new SubObject ();
- $obj2 = clone $obj ;
- print( "Original Object:\n" );
- print_r ( $obj );
- print( "Cloned Object:\n" );
- print_r ( $obj2 );
- /**
- 以上例程会输出:
- Original Object:
- MyCloneable Object
- (
- [object1] => SubObject Object
- (
- [instance] => 1
- ) [object2] => SubObject Object
- (
- [instance] => 2
- ))
- Cloned Object:
- MyCloneable Object
- (
- [object1] => SubObject Object
- (
- [instance] => 3
- ) [object2] => SubObject Object
- (
- [instance] => 2
- ))
- **/
对象比较
PHP 5 中的对象比较要比 PHP 4 中复杂,所期望的结果更符合一个面向对象语言。
当使用比较运算符(==)比较两个对象变量时,比较的原则是:如果两个对象的属性和属性值 都相等,而且两个对象是同一个类的实例,那么这两个对象变量相等。
而如果使用全等运算符(===),这两个对象变量一定要指向某个类的同一个实例(即同一个对象)。
- <?php
- function bool2str ( $bool )
- {
- if ( $bool === false ) {
- return 'FALSE' ;
- } else {
- return 'TRUE' ;
- }
- }
- function compareObjects (& $o1 , & $o2 )
- {
- echo 'o1 == o2 : ' . bool2str ( $o1 == $o2 ) . "\n" ;
- echo 'o1 != o2 : ' . bool2str ( $o1 != $o2 ) . "\n" ;
- echo 'o1 === o2 : ' . bool2str ( $o1 === $o2 ) . "\n" ;
- echo 'o1 !== o2 : ' . bool2str ( $o1 !== $o2 ) . "\n" ;
- }
- class Flag
- {
- public $flag ;
- function Flag ( $flag = true ) {
- $this -> flag = $flag ;
- }
- }
- class OtherFlag
- {
- public $flag ;
- function OtherFlag ( $flag = true ) {
- $this -> flag = $flag ;
- }
- }
- $o = new Flag ();
- $p = new Flag ();
- $q = $o ;
- $r = new OtherFlag ();
- echo "Two instances of the same class\n" ;
- compareObjects ( $o , $p );
- echo "\nTwo references to the same instance\n" ;
- compareObjects ( $o , $q );
- echo "\nInstances of two different classes\n" ;
- compareObjects ( $o , $r );
- /**以上例程会输出:
- Two instances of the same class
- o1 == o2 : TRUE
- o1 != o2 : FALSE
- o1 === o2 : FALSE
- o1 !== o2 : TRUETwo references to the same instance
- o1 == o2 : TRUE
- o1 != o2 : FALSE
- o1 === o2 : TRUE
- o1 !== o2 : FALSEInstances of two different classes
- o1 == o2 : FALSE
- o1 != o2 : TRUE
- o1 === o2 : FALSE
- o1 !== o2 : TRUE
- **/