php如何使用clone关键字克隆class实例化对象
发布于 作者:苏南大叔 来源:程序如此灵动~在编程世界里面,复制一个对象的时候,一定要小心。因为很有可能复制的仅仅是个指针,就是说,原对象如果修改的话,复制体也会被修改。这样的话,可能就和开发人员的本意不一致了。开发人员很可能希望复制出新的对象变量之后,其值并不会因为原对象的改变而改变。
本文的php
关键字是clone
,这个clone
关键词和new
关键词是大概等同的地位。注意:clone
关键字的作用对象,必须是个对象,本文中是个被实例化的类,而不是普通的常见php
变量类型。
基本用法clone $obj
及__clone()
class class1 {
public function __clone() {
}
}
$obj = new class1();
$obj2= clone $obj;
$obj3= clone new class1();
这里要重点说明一下class类中的__clone()
方法,对一个实例化类对象进行clone
关键字操作的时候,如果存在着__clone()
方法,就会自动调用该__clone()
方法。而普通的new
关键词操作,并不会主动调用__clone()
方法。
例如上例中的:
$obj3= clone new class1();
这个就会先调用class1
的__construct
方法,然后调用__clone
方法。clone出来的对象,和原对象相比,是完全独立的个体,两者互不干扰。
当然,如果一个class没有显式的定义__clone
方法方法的话,也是可以clone
的。
强化训练
下面的这个是苏南大叔自己写的一个小题目,大家脑补一下,$c1
/$c2
/$c3
都是什么值呢?正确答案被隐藏了,评论后,就可以显示正确答案。
class class1 {
public $attr1;
private $attr2;
private $attr3;
public function __construct($a1 = "", $a2 = "") {
$this->attr1 = $a1;
$this->attr2 = $a2;
$this->attr3 = "这个是自动化初始值";
}
public function __clone() {
$this->attr3 = "这个是clone时自动生成的值";
}
}
echo "<pre>";
$c1 = new class1("attr1初始值", "attr2初始值");
$c2 = $c1;
$c3 = clone $c1;
$c1->attr1 = "attr1被修改了";
print_r($c1);
print_r($c2);
print_r($c3);
echo "</pre>";
标准答案是:
错误的使用方法
本文中的操作对象是class类,是个object。并不是普通的php变量,如果对一个普通的php变量,比如array
数组进行clone
操作的话,是会报错的。 __clone method called on non-object
。当然,可以使用clone关键字的变量,都会通过is_object()
测试,大家可以试试看。
$d1=["a","b","c"];
$d2=clone $d1;
这里可能存在着一个误区,就是普通的常见php类型变量。还是可以使用=
来复制出一个新的变量的。比如array
,int
之类的非object类型的普通变量类型。换句话说,就是,他们并不需要clone
操作。
比如接着扩展一下本例,大家说$a1
/$a2
/$a3
都是什么值?
$a1 = ["a", "b", "c"];
$a2 = $a1;
$a3 = array_merge([], $a1);
$a1[0] = "aa";
echo "<pre>";
print_r($a1);
print_r($a2);
print_r($a3);
上面这个例子的结果,评论可见。
结论
在php中,恰当的使用clone
关键字,可以减少很多莫名其妙的bug。如果你赋值的变量值经常莫名其妙的改变,试试clone
关键词?当然了,clone
关键字操作,也不是滥用的。比如普通常见类型,就不必使用clone
关键字。
更多php相关经验文章,点击苏南大叔的博客链接吧。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。
赞一个!
写的好