克隆PHP对象并在克隆上设置protected属性

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了克隆PHP对象并在克隆上设置protected属性相关的知识,希望对你有一定的参考价值。

我遇到了一个逻辑问题。

我有一个需要克隆的对象。

对象是|具有计算结果。

该对象具有运行时。

在某些情况下,克隆对象更快,而不是再次计算结果

(f.e。相同的参数^ =相同的结果)。

但是不能复制运行时。

运行时将是确定我可以使用相同结果(对象)的时间。

例:

class Object
{
    protected $runtime;

    public function getRuntime()
    {
        return $this->runtime;
    }

    public function doSome(/*...*/)
    {
        $start = microtime(true);
        // ... the heavy work ...
        // ...
        $this->runtime = microtime(true) - $start;
    }
}

$objects = [];
while (/*...*/) {
    if (count($objects) > 0) {
        $start = microtime(true);
        if (/*check if would get the same result as the previous one*/) {
            $object = clone end($objects);
            // MUST change the runtime here on the clone 
            // but i should not make :runtime public
            $object->runtime = microtime(true) - $start; // :(
            $objects[] = $object;
            continue;
        }
    }
    $object = new Object();
    $object->doSome(/*...*/);
    $objects[] = $object;
}

我怎样才能克隆前一个对象并在克隆上设置实际的运行时而不能使运行时属性公开?

答案

我建议将这个逻辑放在分离的方法Object::clone()中,如下所示:

class Object
{
    protected $runtime;

    public function getRuntime()
    {
        return $this->runtime;
    }

    public function doSome(/*...*/)
    {
        $start = microtime(true);
        // ... the heavy work ...
        // ...
        $this->runtime = microtime(true) - $start;
    }

    public static function clone($clonable, $runtime)
    {
        $clone = clone $clonable;
        $clone->runtime = $runtime; // we can access it since we are in Object scope
        return $clone;
    }
}

$objects = [];
while (/*...*/) {
    if (count($objects) > 0) {
        $start = microtime(true);
        if (/*check if would get the same result as the previous one*/) {
            $object = Object::clone(end($objects), microtime(true) - $start);
            $objects[] = $object;
            continue;
        }
    }
    $object = new Object();
    $object->doSome(/*...*/);
    $objects[] = $object;
}

另一个选择是为runtime属性实现setter方法

另一答案

使用魔法:

克隆完成后,如果定义了__clone()方法,则将调用新创建的对象的__clone()方法,以允许任何需要更改的必要属性。

http://php.net/manual/en/language.oop5.cloning.php#object.clone

class Object
{
    protected $runtime;

    public function __clone() {
        //set $this->runtime
    }
}    

以上是关于克隆PHP对象并在克隆上设置protected属性的主要内容,如果未能解决你的问题,请参考以下文章

如何克隆 Django 模型实例对象并在 Django 表单上显示?

高级OOP特性

php对象克隆

什么是 php 中的对象克隆?

对象引用与对象克隆

从克隆(深浅拷贝)到原型设计模式