3

新しいオブジェクトの参照が元のオブジェクトのメソッドとプロパティではなく、独自のメソッドとプロパティを指すように、それ自体への多くの参照を含む複雑なPHPオブジェクトのクローンを作成するための最良の方法は何ですか?

私は、それらがどこにあるかを参照し続ける浅いコピーを作成するマニュアルから理解しています。$new_object = clone $old_object;では、おそらく$ new_objectの参照は、古いオブジェクトのメソッドを指しているのでしょうか。

そのマニュアルページへのコメントは、それ$new_object = unserialize(serialize($old_object));がディープコピーを作成する方法であることを示唆しています。有望に聞こえますが、このアプローチが私の場合に何を意味するのか正確にはわかりません。参照がクローンを指すように変換されるのか、絶対になるのか、それとも他の何かになるのか、そして私が望むことを行うのであれば、それが最善の方法であるかどうかです。

これを行うための確立された標準的な方法があるかどうか知りたいのですが。

(注:問題のオブジェクトはDrupal Viewsオブジェクトですが、この質問は一般的なPHPオブジェクトに関するものです。このオブジェクトの唯一の重要な機能は、巨大であり、ナビゲートしようとすると繰り返されるそれ自体への多くの参照が含まれていることです。ツリー全体。)

4

2 に答える 2

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);

このコードは、自己参照がクローンを指していることを示しています。http://codepad.org/dSnZ5I10

于 2012-04-09T16:29:53.030 に答える
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())、無限ループや過度の再帰でクラッシュすることはありません。これが最良の、標準的な、および/または受け入れられたアプローチであるかどうかについての人々の考えを聞きたいです。

于 2012-04-09T16:31:15.897 に答える