原文地址: http://www.nowamagic.net/librarys/posts/php/32

PHP4面向对象功能一个很大的缺点,是将对象视为另一种数据类型,这使得很多常见的OOP方法无法使用,如设计模式。这些方法依赖于将对象作为引用传递给其他类方法,而不是作为值传递,而按值传递却是PHP的默认做法。幸好,PHP5解决了这个问题,现在所有对象在默认情况下都被视为引用。但是,由于所有对象都被视为引用而不是值,所以现在复制对象更为困难。如果尝试复制一个引用的对象,这只会指向原对象的地址位置。为了解决复制问题,PHP提供了一种克隆(clone)对象的显式方法。

对象克隆 可以在对象前面加clone关键字来克隆对象,如下:

 destinationObject = clone targetObject;

下面将给出一个详细的对象克隆示例。

这个例子使用一个名为Corporate_Drone的示例类,它包含两个成员(employeeid和tiecolor),并有相应的获取方法和设置方法。

此代码首先实例化一个corporatedrone对象,并以此为基础展示克隆操作的效果:

 <?php
class corporatedrone {
private $employeeid;
private $tiecolor;
// Define a setter and getter for $employeeid
function setEmployeeID($employeeid) {
$this->employeeid = $employeeid;
}
function getEmployeeID() {
return $this->employeeid;
}
// Define a setter and getter for $tiecolor
function setTiecolor($tiecolor) {
$this->tiecolor = $tiecolor;
}
function getTiecolor() {
return $this->tiecolor;
}
}
// Create new corporatedrone object
$drone1 = new corporatedrone(); // Set the $drone1 employeeid member
$drone1->setEmployeeID("12345"); // Set the $drone1 tiecolor member
$drone1->setTiecolor("red"); // Clone the $drone1 object
$drone2 = clone $drone1; // Set the $drone2 employeeid member
$drone2->setEmployeeID("67890"); // Output the $drone1 and $drone2 employeeid members
echo "drone1 employeeID: ".$drone1->getEmployeeID()."<br />";
echo "drone1 tie color: ".$drone1->getTiecolor()."<br />";
echo "drone2 employeeID: ".$drone2->getEmployeeID()."<br />";
echo "drone2 tie color: ".$drone2->getTiecolor()."<br />";
?>
输出结果为:
drone1 employeeID: 12345
drone1 tie color: red
drone2 employeeID: 67890
drone2 tie color: red

$drone2变成一个Corporate_Drone类型的对象,并继承了$drone1的成员值。为进一步展示$drone2确实是Comporate_Drone类型,这里还重新对employeeid成员进行了赋值

__clone()方法

可以在对象类中定义一个__clone()方法来调整对象的克隆行为。此方法的代码将在克隆操作期间执行。除了将所有现有对象成员复制到目标对象之外,还会执行__clone()方法指定的操作。下面修改Corporate_Drone类,增加以下方法:

 function __clone() {
$this->tiecolor = "blue";
}

之后,创建一个新的Corporate_Drone对象,增加employeeid成员的值,克隆这个对象,然后输出一些数据,从而显示克隆对象的tiecolor确实是通过__clone()方法设置的。

示例代码:

 <?php
// Create new corporatedrone object
$drone1 = new corporatedrone(); // Set the $drone1 employeeid member
$drone1->setEmployeeID("12345"); // Clone the $drone1 object
$drone2 = clone $drone1; // Set the $drone2 employeeid member
$drone2->setEmployeeID("67890"); // Output the $drone1 and $drone2 employeeid members
echo "drone1 employeeID: ".$drone1->getEmployeeID()."<br />";
echo "drone2 employeeID: ".$drone2->getEmployeeID()."<br />";
echo "drone2 tiecolor: ".$drone2->getTiecolor()."<br />";
?>
输出结果为:
drone1 employeeID: 12345
drone2 employeeID: 67890
drone2 tiecolor:

将一个类赋值给另一个类,此时内存中仍是一个对象:

 <?php
class Fruit {
private $name = "水果";
private $color = "颜色"; public function setName($name){
$this->name = $name;
} public function setColor($color){
$this->color = $color;
} function showColor(){
return $this->color.'的'.$this->name."<br />";
} function __destruct(){
echo "被吃掉了(对象被回收) <br />";
}
} $apple = new Fruit();
$apple->setName("大苹果");
$apple->setColor("红色");
echo $apple->showColor(); $clone_apple = $apple;
$clone_apple->setName("小苹果");
$clone_apple->setColor("青色"); echo $clone_apple->showColor();
?>
输出结果为:
红色的大苹果

青色的小苹果
被吃掉了(对象被回收)

clone方法克隆出了一个新的类,此时内存中有两个对象:

 <?php
class Fruit {
private $name = "水果";
private $color = "颜色"; public function setName($name){
$this->name = $name;
} public function setColor($color){
$this->color = $color;
} function showColor(){
return $this->color.'的'.$this->name."<br />";
} function __destruct(){
echo "被吃掉了(对象被回收) <br />";
}
function __clone(){
$this->name = "克隆水果";
}
} $apple = new Fruit();
$apple->setName("大苹果");
$apple->setColor("红色");
echo $apple->showColor();
echo "<hr/>";
$clone_apple = clone $apple;
$clone_apple->setColor("青色"); echo $clone_apple->showColor();
?>
输出结果为:
红色的大苹果

青色的克隆水果
被吃掉了(对象被回收)
被吃掉了(对象被回收)

php魔术函数 __clone()的更多相关文章

  1. PHP5中常用的魔术函数有哪些,举例说明各自的用法。

    所谓魔术函数,是指不同时刻为了完成特定的功能,而自动调用的方法. __sleep       在serialize()序列化对象之前会调用这个函数__wakeup    在unserialize()解 ...

  2. php5魔术函数、魔术常量

    魔术函数 1.__construct()  实例化对象时被调用,  当__construct和以类名为函数名的函数同时存在时,__construct将被调用,另一个不被调用. 2.__destruct ...

  3. PHP 魔术变量和魔术函数详解

    魔术变量 PHP 向它运行的任何脚本提供了大量的预定义常量. 不过很多常量都是由不同的扩展库定义的,只有在加载了这些扩展库时才会出现,或者动态加载后,或者在编译时已经包括进去了. 有八个魔术常量它们的 ...

  4. PHP超级全局变量、魔术变量和魔术函数

    PHP超级全局变量(9个) $GLOBALS 储存全局作用域中的变量 $_SERVER 获取服务器相关信息 $_REQUEST 获取POST和GET请求的参数 $_POST 获取表单的POST请求参数 ...

  5. php魔术变量和13个PHP魔术函数

    PHP魔术变量确切地说是PHP魔术常量,不过很多常量都是由不同的扩展库定义的,只有在加载了这些扩展库时才会出现,或者动态加载后,或者在编译时已经包括进去了.比如说__LINE__放在不同的地方是显示不 ...

  6. PHP超级全局变量、魔术变量和魔术函数的区别和联系

    PHP超级全局变量.魔术变量和魔术函数的区别和联系 一.总结 一句话总结:PHP超级全局变量主要用于web开发,魔术变量主要用于输出当前对象的信息,魔术函数则是对象的常用方法 相同点: 1.PHP超级 ...

  7. Atitit.跨平台预定义函数 魔术方法 魔术函数 钩子函数 api兼容性草案 v2 q216  java c# php js.docx

    Atitit.跨平台预定义函数 魔术方法 魔术函数 钩子函数 api兼容性草案 v2 q216  java c# php js.docx 1.1. 预定义函数 魔术方法 魔术函数是什么1 1.2. & ...

  8. PHP魔术函数、魔术常量、预定义常量

    一.魔术函数(13个) 1.__construct() 实例化对象时被调用, 当__construct和以类名为函数名的函数同时存在时,__construct将被调用,另一个不被调用. 2.__des ...

  9. 详解PHP魔术函数、魔术常量、预定义常量

    一.魔术函数(13个) 1.__construct() 实例化对象时被调用, 当__construct和以类名为函数名的函数同时存在时,__construct将被调用,另一个不被调用. 2.__des ...

随机推荐

  1. HTTP压力测试工具wrk的安装及测试

    本次在VMware虚拟机的CentOS6.3系统中进行安装wrk压测工具,具体如下: 一.预先安装需求项 为了安装顺利,不受权限的限制,首先可以把用户切换为root用户# su + 输入root用户对 ...

  2. JVM内存模型一

    JVM定义了若干个程序执行期间使用的数据区域.这个区域里的一些数据在JVM启动的时候创建,在JVM退出的时候销毁.而其他的数据依赖于每一个线程,在线程创建时创建,在线程退出时销毁. 程序计数器 程序计 ...

  3. 左连接,右连接和等值连接(left join,right join和inner join)

    left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录inner join(等值连接) 只 ...

  4. MT【130】Heilbronn问题

    (清华THUSSAT,多选题) 平面上 4 个不同点 \(P_1,P_2,P_3,P_4\),在每两个点之间连接线段得到 6 条线段. 记 \[L=\max_{1\leq i<j\leq 4}| ...

  5. 浅谈博弈论之Nim初步(xor正确性的浅显证明)

    引入 在许多地方曾流行过这样一个小游戏:摆出三堆硬币,分别包含3枚,5枚,7枚.两人轮流行动,每次可任选一堆,从中取走任意多枚硬币,可把一堆取光,但不能不取,取走最后一枚硬币者获胜. 概念 \(先手: ...

  6. 【题解】CF#896 D-Nephren Runs a Cinema

    容易发现这些 vip 用户并没什么用,所以考虑枚举手持50元与100元的人共有多少个.设手持50元的人 \(a\) 个,手持100元的人 \(a - k\) 个,那么一共是 \(2*a - k\) 个 ...

  7. 【2018ICPC青岛】

    B 题意:给n个问题,每个问题有一个固定的答案ai(<=10^5).现在有m个约束关系,每个约束关系是一个二元组(ui,vi),表示你回答ui.vi问题的答案必须一样. 现在让你输出分别修复一个 ...

  8. 浅谈Tarjan算法及思想

    在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连 ...

  9. BZOJ5305 [Haoi2018]苹果树 【组合数学】

    题目链接 BZOJ5305 题解 妙啊 要求的是所有可能的树形的所有点对距离和 直接考虑点的贡献肯定想不出,这样的所有点对距离问题通常转化为边的贡献 考虑一条边会产生多少贡献 我们枚举\(i\)节点的 ...

  10. BZOJ2436 [Noi2011]Noi嘉年华 【dp】

    题目链接 BZOJ2436 题解 看这\(O(n^3)\)的数据范围,可以想到区间\(dp\) 发现同一个会场的活动可以重叠,所以暴力求出\(num[l][r]\)表示离散化后\([l,r]\)的完整 ...