PHP の浅いコピーと深いコピーの詳細な例
前書き:
最近デザインパターンの知識を見直したところ、プロトタイプパターンデザインパターンを見て、これには次のような質問があることに気づきました。浅いコピーと深いコピー。ここでそれを要約し、今後さらに注意を払うように自分に言い聞かせましょう。
PHP5 以降、newoperator は自動的に参照を返すようになりました。オブジェクト変数はオブジェクト全体の値を格納するのではなく、実際のオブジェクトのコンテンツにアクセスするための識別子のみを格納します。オブジェクトがパラメータとして渡されるか、結果として返されるか、または別の変数に割り当てられる場合、他の変数には元の変数との参照関係はありませんが、どちらも同じ識別子のコピーを格納し、オブジェクトの実際の内容を指します。同じオブジェクトです。
例は次のとおりです:
class Example1 { public $name; public function construct($name) { $this->name = $name; } } $ex1 = new Example('test1');// $ex1->name现在是:test1 $ex2 = $ex1;// $ex2->name现在是:test1 $ex2->name = 'test2';// 这样修改一下之后,$ex1->name与$ex2->name都变为了:test2
上記の例を通して、オブジェクト間の参照の概念を理解できるはずです。それでは、PHP で clone キーワードを指定して オブジェクトのコピー を実行するか、
$ex1 = new Example('test1');// $ex1->name现在是:test1 $ex2 = clone $ex1;//$ex2->name现在是:test1 $ex2->name = 'test2';//现在$ex1->name还是test1,而$ex2->name是test2
ここでわかるように、クローン作成後、$ex1 と $ex2 は 2 つの異なるオブジェクトになり、それぞれに独自の変数環境があります。ただし、これら 2 つのオブジェクトの内部で所有されているのは値型のデータであることに注意してください。内部的に所有されているのが参照型の場合、クローン作成によって取得された新しいオブジェクト内の参照は依然として元の参照を指します。浅いコピーと深いコピーの概念は次のとおりです:
浅いコピー: クローンを使用してオブジェクトをコピーします。この種のコピーは、割り当てられたオブジェクトのすべての変数が元の値と同じままです。オブジェクト、および他のオブジェクトへのすべての参照は依然として元のオブジェクトを指します。
ディープコピー: コピーされたオブジェクトのすべての変数には、他のオブジェクトを参照する変数を除き、元のオブジェクトと同じ値が含まれます。
クローンのデフォルトの使用法は浅いコピーを実行することですが、どうすれば深いコピーを実行できるでしょうか?
方法1:クローンメソッドを使う
public function clone() { $this->obj = new Obj(); }
この方法は非常に直感的ですが、クラス内に複数の参照が含まれている場合、クラス内で参照を一つ一つリセットする必要があるという非常に面倒な操作方法を持っています。クローンメソッド。そして、いくつかの 周期的参照の問題にも対処する必要があります。とても複雑です。
方法2:シリアル化(冷凍・解凍)を使用する
$tmp = serialize($ex1); $ex2 = unserialize($tmp);
このとき取得した$ex2は、まったく新しいオブジェクトです。この処理は、Javaでは「冷凍」および「解凍」処理とも呼ばれます。
シリアル化は再帰的なプロセスです。オブジェクト内で参照されるオブジェクトの数や、参照されるオブジェクトのレイヤーの数を気にする必要はありません。それらを完全にコピーできます。方法 2 は本当にポルノ的で暴力的ですが、私はとても気に入っています。
以上がphpでの浅いコピーと深いコピーの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。