PHP - 克隆一个包含对自身引用的对象?

时间:2012-04-09 16:24:36

标签: php oop drupal cloning self-reference

创建复杂PHP对象的克隆的最佳方法是什么,该对象包含对自身的许多引用,以便新对象的引用指向其自己的方法和属性,而不是原始对象的方法和属性?

我理解from the manual $new_object = clone $old_object;创建一个浅层副本,将引用保留在原来的位置。所以$ new_object的引用可能会指向旧对象上的方法?

对该手册页的评论表明,$new_object = unserialize(serialize($old_object));是一种创建深层副本的方法。听起来很有希望,我不确定这种方法究竟对我的情况意味着什么:引用是转换为指向克隆,还是绝对,或其他什么,如果确实做了我想要的,那么它是否是最好的方式。

我想知道是否有一种既定的,标准的方法来做到这一点。

(注意:有问题的对象是Drupal Views对象,但这个问题一般是关于PHP对象的:这个对象唯一重要的特性是,它是巨大的,并且包含许多对自身的引用,如果您尝试导航整个树,则递归。)

2 个答案:

答案 0 :(得分:3)

一个简单的测试将揭示会发生什么:

$old = new stdClass();
$old->foo = 'bar';
$old->baz = &$old;

print_r($old);

$new = unserialize(serialize($old));

$new->foo = 'new';

print_r($new);
print_r($new->baz->foo);

此代码显示self-ref现在指向克隆。 http://codepad.org/dSnZ5I10

答案 1 :(得分:2)

这是一些基本的测试和结果。不是一个完整的答案,但希望有用。如果我的方法有误,请纠正我。假设$ view是一个已包含大量自引用和数据加载的对象:

      $view->somedata = "This is the default";
      $view->selfreference =& $view->somedata;

      $new = clone $view;
      $new2 = unserialize(serialize($view));

      $view->somedata = "This is view";
      $new->somedata = "This is new";
      $new2->somedata = "This is new2";

      echo("$view: ".$view->selfreference);
      echo("$new: ".$new->selfreference);
      echo("$new2: ".$new2->selfreference);

结果:

'$view: This is new'
'$new: This is new'
'$new2: This is new2'

因此,在第一次调查时,看起来像clone的浅层克隆指向对原始的自引用,unserialize(serialize())方法维护引用并将其指向新对象。

所以看起来unserialize(serialize())可以工作,并且不会因无限循环或过度递归而崩溃。我想听听人们对这是一种最佳,标准和/或接受的方法的看法。