php中对象克隆和一个简单的单列类

7 篇文章 0 订阅
4 篇文章 0 订阅

在多数情况下,我们并不需要完全复制一个对象来获得其中的属性。但有一个情况下确实需要:如果你有一个GTK窗口对象,该对象持有窗口的相关资源。

你可能会想复制一个新的窗口,保持所有属性与原来的窗口相同,但必须是一个新的对象(因为如果不是一个新的对象,那么一个窗口中的改变就会影响到另一个窗口)。

还有一种情况:如果对象A中保持着对象B的引用,当你复制对象A时,你想其中使用的对象不再是对象B而是B的一个副本,那么你必须得到对象A的一个副本。

对象复制可以通过clone关键字来完成(如果可能,这将调用对象的__clone()方法)。对象中的__clone()方法不能被直接调用,否则会报一个致命错误(Fatal error: Cannot call __clone() method on objects - use 'clone $obj')。

当对象被复制后,PHP5会对对象的所有的属性执行一个浅复制(shallow copy)。所有的引用属性任然是一个指向原来的变量的引用

当复制完成时,如果定义了__clone()方法,则新创建的对象(复制生成的对象)中的__clone()方法会被调用,可用于修改属性的值(如果有必要的话)。

下面例子证明了上面两条:

class SubObject
{
    
}

class MyCloneable
{
    public $object1;
    public $object2;

    function __clone()
    {

        // 强制复制一份this->object, 否则仍然指向同一个对象
        $this->object1 = clone $this->object1;
    }
}

$obj = new MyCloneable();

$obj->object1 = new SubObject();
$obj->object2 = new SubObject();

$obj2 = clone $obj;


print("Original Object:\n");
var_dump($obj);

print("Cloned Object:\n");
var_dump($obj2);

运行结果如下,注意看对象编号:


我们会发现,的确是浅复制。

所以我们在做单列类的时候,别人也可能会用克隆的方式来复制我们的对象,怎么办呢,其实很简单,只要我们让__clone()方法不可访问就可以了,代码如下:

class Person {
    private static $obj;
    public function say()
    {
        echo '我是人类';
    }

    public static function construct()
    {
        if(!self::$obj){
            self::$obj = new self();
        }
        return self::$obj;
    }

    private function __construct(){}

    private function __clone(){}
}

$person = Person::construct();

如果我们克隆对象的时候,就会报一个致命错误(Fatal error: Call to private Person::__clone() from context '')。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值