PHP 4.0中没有提供一种机制来让用户自己定义复制构造子(copy constructor)控制对象的复制过程。PHP 4版本中所做的二进制拷贝,能够很精确地复制了对象的所有属性。精确地复制对象的所有属性可能并不是我们一直想要的。有个例子可以很好地说明我们确实需要复制构造子:比如一个GTK Window的对象a。a持有它所需要的全部资源。当复制的这个GTK Window到对象b时候,我们更希望b持有新的资源对象。再举个例子:对象a包含了一个对象c,当你把对象a 复制到对象c的时候。我们可能更希望对象b包含一个新的对象c的copy,而不是一个对象c的引用。
换句话说,我们复制一个对象不仅仅是需要该对象的现有的一切属性。如我们需要的是复制的对象的方法能够在新的参数下进行操作,得到新的结果。复制过来的是一种新的结构,新的形态。下面我们将以例子的形式阐述一下克隆的概念。
PHP 5中的对象模型通过引用来调用对象,但有时可能想建立一个对象的副本,并希望原来的对象的改变不影响到副本。为了这样的目的,PHP定义了一个特殊的方法,称为__clone。像__construct和__destruct一样,前面有两个下划线。默认地,用__clone方法将建立一个与原对象拥有相同属性和方法的对象。如果想在克隆时改变默认的内容,要在__clone()方法中重写属性或方法。克隆的方法可以没有参数,但它同时包含this和that指针(that指向被复制的对象)。如果选择克隆自己,要小心复制任何对象包含的信息,从that到this。如果用__clone来复制,PHP不会执行任何隐性的复制,
当一个对象被克隆时,PHP 5将执行一个所有对象的属性的浅拷贝。任何对其他变量引用的属性将只保留引用。如果一个__clone()方法被定义,然后重新创建一个对象的克隆方法来允许任何必需的属性当它需要被改变时调用。
把一个类的对象克隆成另外一个对象,语法格式如下:
$copy_of_object = clone $object;
在上述的代码中,$copy_of_object是一个通过克隆产生的新对象,$object是一个被克隆的对象。
现在创建一个案例,演示一下克隆的过程及使用。该案例的代码如下:
案例6-1
<?php
class foo {
private $x;
private $y;
function setX($x) {
$this->x = $x;
}
function getX() {
return $this->x;
}
function setY($y) {
$this->y = $y;
}
function getY() {
return $this->y;
}
}
$o1 = new foo;
$o1->setX(4);
$o1->setY(8);
$o2 =clone $o1;
$o2->setX(5);
if($o1->getX() != $o2->getX())
print("值不相等");
echo "<br>o1对象的值为:";
echo $o1->getX();
echo " ";
echo $o1->getY();
echo "<br>o2对象的值为:";
echo $o2->getX();
echo " ";
echo $o2->getY();
?>
将上述代码保存,名称为clone.php,该文件保存到C:\Web\apache\htdocs\class目录的下面,本章的案例都是保存该目录下,以后不再特别声明。打开IE浏览器,在地址栏中输入http://localhost:8080/class/clone.php,直接可以运行了。