PHP编程中的__clone()方法使用详解


Posted in PHP onNovember 27, 2015

可以在对象类中定义一个__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();
?>

上面只是将一个类赋值给另一个类,所以此时内存中仍是一个对象。

<?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();

$clone_apple = clone $apple;
$clone_apple->setColor("青色");

echo $clone_apple->showColor();
?>

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

php的__clone()方法对一个对象实例进行的浅复制,对象内的基本数值类型进行的是传值复制,而对象内的对象型成员变量,如果不重写__clone方法,显式的clone这个对象成员变量的话,这个成员变量就是传引用复制,而不是生成一个新的对象.如下面一个例子的第28行注释所说

<?php
  class Account {
    public $balance;
    
    public function __construct($balance) {
      $this->balance = $balance;
    }
  }
 
  class Person {
    private $id;
    private $name;
    private $age;
    public $account;
    
    public function __construct($name, $age, Account $account) {
      $this->name = $name;
      $this->age = $age;
      $this->account = $account;
    }
    
    public function setId($id) {
      $this->id = $id;
    }
    
    public function __clone() {  #复制方法,可在里面定义再clone是进行的操作
      $this->id = 0;
      $this->account = clone $this->account;  #不加这一句,account在clone是会只被复制引用,其中一个account的balance被修改另一个也同样会被修改
    }
  }
  
  $person = new Person("peter", 15, new Account(1000));
  $person->setId(1);
  $person2 = clone $person;
  
  $person2->account->balance = 250;
  
  var_dump($person, $person2);
  
 ?>

输出:

object(Person)#1 (4) { ["id":"Person":private]=> int(1) ["name":"Person":private]=> string(5) "peter" ["age":"Person":private]=> int(15) ["account"]=> object(Account)#2 (1) { ["balance"]=> int(1000) } } object(Person)#3 (4) { ["id":"Person":private]=> int(0) ["name":"Person":private]=> string(5) "peter" ["age":"Person":private]=> int(15) ["account"]=> object(Account)#4 (1) { ["balance"]=> int(250) } }
PHP 相关文章推荐
PHP安装全攻略:APACHE
Oct 09 PHP
ThinkPHP实现多数据库连接的解决方法
Jul 01 PHP
codeigniter中view通过循环显示数组数据的方法
Mar 20 PHP
php 类自动载入的方法
Jun 03 PHP
PHP基于文件存储实现缓存的方法
Jul 20 PHP
WordPress迁移时一些常见问题的解决方法整理
Nov 24 PHP
验证坐标在某坐标区域内php代码
Oct 08 PHP
通过chrome浏览器控制台(Console)进行PHP Debug的方法
Oct 19 PHP
thinkphp集成前端脚手架Vue-cli的教程图解
Aug 30 PHP
PHP生成短网址的思路以及实现方法的详解
Mar 25 PHP
ThinkPHP框架整合微信支付之Native 扫码支付模式二图文详解
Apr 09 PHP
tp5.1 框架查询表达式用法详解
May 25 PHP
PHP通过反射动态加载第三方类和获得类源码的实例
Nov 27 #PHP
基于php实现随机合并数组并排序(原排序)
Nov 26 #PHP
PHP随手笔记整理之PHP脚本和JAVA连接mysql数据库
Nov 25 #PHP
php实现遍历多维数组的方法
Nov 25 #PHP
WordPress迁移时一些常见问题的解决方法整理
Nov 24 #PHP
基础的WordPress插件制作教程
Nov 24 #PHP
优化WordPress的Google字体以加速国内服务器上的运行
Nov 24 #PHP
You might like
php学习之运算符相关概念
2011/06/09 PHP
PHP中使用GD库绘制折线图 折线统计图的绘制方法
2015/11/09 PHP
针对thinkPHP5框架存储过程bug重写的存储过程扩展类完整实例
2018/06/16 PHP
PDO::inTransaction讲解
2019/01/28 PHP
php微信分享到朋友圈、QQ、朋友、微博
2019/02/18 PHP
PHP设计模式之适配器模式(Adapter)原理与用法详解
2019/12/12 PHP
jquery实现的超出屏幕时把固定层变为定位层的代码
2010/02/23 Javascript
EXTJS FORM HIDDEN TEXTFIELD 赋值 使用value不好用的问题
2011/04/16 Javascript
JavaScript面向对象程序设计三 原型模式(上)
2011/12/21 Javascript
最佳6款用于移动网站开发的jQuery 图片滑块插件小结
2012/07/20 Javascript
Android中的jQuery:AQuery简介
2014/05/06 Javascript
node.js中的events.EventEmitter.listenerCount方法使用说明
2014/12/08 Javascript
jQuery简单几行代码实现tab切换
2015/03/10 Javascript
javascript去除空格方法小结
2015/05/21 Javascript
JS获取短信验证码倒计时的实现代码
2017/05/22 Javascript
详解angular ui-grid之过滤器设置
2017/06/07 Javascript
angular6 利用 ngContentOutlet 实现组件位置交换(重排)
2018/11/02 Javascript
[03:23:49]2016.12.17日完美“圣”典全回顾
2016/12/19 DOTA
python中实现定制类的特殊方法总结
2014/09/28 Python
Python selenium如何设置等待时间
2016/09/15 Python
Python数据结构与算法之完全树与最小堆实例
2017/12/13 Python
详谈python3中用for循环删除列表中元素的坑
2018/04/19 Python
python多进程使用及线程池的使用方法代码详解
2018/10/24 Python
python实现一个简单的ping工具方法
2019/01/31 Python
使用django的objects.filter()方法匹配多个关键字的方法
2019/07/18 Python
python 实现矩阵填充0的例子
2019/11/29 Python
Pycharm中import torch报错的快速解决方法
2020/03/05 Python
python 元组的使用方法
2020/06/09 Python
python怎么对数字进行过滤
2020/07/05 Python
美国东北部户外服装和设备零售商:Eastern Mountain Sports
2016/10/05 全球购物
Coccinelle官网:意大利的著名皮具品牌
2019/05/15 全球购物
学校运动会霸气口号
2014/06/07 职场文书
幼儿园课题方案
2014/06/09 职场文书
白莲教口号
2014/06/18 职场文书
党员批评与自我批评
2014/10/15 职场文书
小学五年级语文上册教学计划
2015/01/22 职场文书