【问题标题】:PHP clone keyword [duplicate]PHP克隆关键字[重复]
【发布时间】:2012-08-25 02:05:00
【问题描述】:

可能重复:
what is Object Cloning in php?

我正在研究一个经常使用“克隆”关键字的现有框架,不确定这样做是否是个好主意?我真的不明白需要使用“克隆”关键字。

例如看看这个编码

  public function getStartDate ()
  {
    return clone $this->startDate;
  }

对我来说这个函数应该如下所示,我看不出克隆的需要。

  public function getStartDate ()
  {
    return $this->startDate;
  }

【问题讨论】:

标签: php


【解决方案1】:

使用 clone 的原因是 PHP 在处理对象时总是返回对象作为引用,而不是作为副本。

这就是为什么在将对象传递给函数时不需要用 & (引用)指定它:

function doSomethingWithObject(MyObject $object) { // it is same as MyObject &object
   ...
}

因此,为了获得对象副本,您必须使用 clone 关键字 这是一个关于 php 如何处理对象以及 clone 做什么的示例:

class Obj {
    public $obj;
    public function __construct() {
        $this->obj = new stdClass();
        $this->obj->prop = 1; // set a public property
    }
    function getObj(){
        return $this->obj; // it returns a reference
    }
}

$obj = new Obj();

$a = $obj->obj; // get as public property (it is reference)
$b = $obj->getObj(); // get as return of method (it is also a reference)
$b->prop = 7;
var_dump($a === $b); // (boolean) true
var_dump($a->prop, $b->prop, $obj->obj->prop); // int(7), int(7), int(7)
// changing $b->prop didn't actually change other two object, since both $a and $b are just references to $obj->obj

$c = clone $a;
$c->prop = -3;
var_dump($a === $c); // (boolean) false
var_dump($a->prop, $c->prop, $obj->obj->prop); // int(7), int(-3), int(7)
// since $c is completely new copy of object $obj->obj and not a reference to it, changing prop value in $c does not affect $a, $b nor $obj->obj!

【讨论】:

    【解决方案2】:

    也许startDate 是一个对象。

    那么。当您返回 clone $this->startDate 时 - 您将获得该对象的完整副本。您可以使用它、更改值、调用函数。而且,在它们影响数据库或文件系统之前 - 它是安全的,实际的 startDate 对象不会被修改。

    但是,如果你只是按原样返回对象 - 你只返回一个引用。以及您对对象执行的任何操作 - 您对原始对象执行此操作。您所做的任何更改 - 都会影响到 startDate

    这仅适用于对象,不会影响数组、字符串和数字,因为它们是值类型变量。

    您应该阅读有关值类型变量和引用类型变量的更多信息。

    【讨论】:

      【解决方案3】:

      尽管它在another question 中得到了完美的解释(感谢@gerald 指出这个)

      只是一个简单的答案:

      如果没有克隆,该函数将返回对 startDate 对象的引用。随着克隆它返回一个副本。

      如果返回的对象稍后会被更改,它只会更改副本而不更改原始对象,原始对象也可能会在其他地方使用。

      【讨论】:

      • 但问题在于完全面向对象的设计中,我们需要传递实际对象而不是克隆对象,不是吗?对我来说,当 OO 设计实践使用时,这种使用克隆对象的设计在一个类中是不正确的..
      猜你喜欢
      • 2011-10-19
      • 2020-03-04
      • 2010-09-29
      • 1970-01-01
      • 2017-06-13
      • 2022-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多