原文地址: 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. Java乐观锁、悲观锁

    乐观锁 乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号 ...

  2. c++11 智能指针 unique_ptr、shared_ptr与weak_ptr

    c++11 智能指针 unique_ptr.shared_ptr与weak_ptr C++11中有unique_ptr.shared_ptr与weak_ptr等智能指针(smart pointer), ...

  3. Oracle 双字段过滤

    白名单:数据 id ,  g_id,sys_id 1,2,3 1,2,4   黑名单:数据 id ,  g_id,sys_id b,2,3   结果  1,2,4      select t1.*   ...

  4. 【刷题】BZOJ 1061 [Noi2008]志愿者招募

    Description 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能完 ...

  5. 【BZOJ3551】Peaks加强版(Kruskal重构树,主席树)

    [BZOJ3551]Peaks加强版(Kruskal重构树,主席树) 题面 BZOJ Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相 ...

  6. BZOJ4036 [HAOI2015]按位或 【minmax容斥 + 期望 + FWT】

    题目链接 BZOJ4036 题解 好套路的题啊,,, 我们要求的,实际上是一个集合\(n\)个\(1\)中最晚出现的\(1\)的期望时间 显然\(minmax\)容斥 \[E(max\{S\}) = ...

  7. Java EE之会话

    1.需要会话的原因 所有HTTP服务器技术都普遍采用HTTP会话的概念,并且Java EE也在规范中添加了对会话的支持. 维持状态 会话用于维持请求和请求之间的状态.HTTP请求自身是完全无状态的.从 ...

  8. 解题:USACO15JAN Grass Cownoisseur

    解题 首先缩点没啥可说的,然后考虑枚举这次逆行的边.具体来说在正常的图和反图上各跑一次最长路,然后注意减掉起点的贡献,用拓扑排序实现(我这里瞎写了个Bellman_Ford,其实在DAG上这好像和拓扑 ...

  9. bzoj 3611: [Heoi2014]大工程 && bzoj 2286: [Sdoi2011消耗战

    放波建虚树的模板. 大概是用一个栈维护根节点到当前关键点的一条链,把其他深度大于lca的都弹出去. 每次做完记得复原. 还有sort的时候一定要加cmp!!! bzoj 3611 #include&l ...

  10. GoLand语言快捷键

    快捷键 作用 备注 ctrl + n 导航到类名 ctrl + shift + n 导航到文件 ctrl + e/ctrl + shift + e 打开到最近的文件/打开最近修改的文件 ctrl + ...