参考リンク:
1. php.net 公式 Web サイトのドキュメント - オブジェクトのコピー
いつ使用しますか? php.net からの抜粋:
ほとんどの場合、オブジェクトのプロパティを取得するためにオブジェクトを完全にコピーする必要はありません。ただし、これが本当に必要となるケースが 1 つあります。それは、ウィンドウ関連のリソースを保持する GTK ウィンドウ オブジェクトがある場合です。元のウィンドウと同じプロパティをすべて保持したまま新しいウィンドウをコピーしたい場合がありますが、それは新しいオブジェクトである必要があります (新しいオブジェクトでない場合、一方のウィンドウでの変更がもう一方のウィンドウに影響するため)。別の状況もあります。オブジェクト A がオブジェクト B への参照を保存している場合、オブジェクト A をコピーするときに、そこで使用されるオブジェクトをオブジェクト B ではなく B のコピーにしたい場合は、オブジェクト A のコピーを取得する必要があります。 。
最も単純な「=」を使用してみてください
最初に明確にしておきたいのは、PHP オブジェクトは識別子とともに保存されるため、オブジェクトへの直接の「代入」動作は「参照による受け渡し」と同等です
出力結果は次のとおりです:
オブジェクト識別子としての #n は、$a1 と $a2 が実際には同じオブジェクトを指しており、$a3 は別のオブジェクトであることを示していることがわかります
そのため、まったく新しいオブジェクトをコピーする必要がある場合、= を使用して直接コピーすることはできません。それ以外の場合、$a1->a を変更することは、$a2->a を変更することと同じです。
浅いコピー
PHP5 では、クラスにマジック メソッド __clone() があり、clone キーワードとオブジェクトとともに使用すると自動的に呼び出されます (明示的に定義されていない場合は、空のメソッドが呼び出されます)。
clone キーワードの機能は、オブジェクトをコピーしてオブジェクトの「浅いコピー」を形成し、それを新しいオブジェクトに割り当てることです。このときのオブジェクト識別子は異なります。
出力結果は次のとおりです:
ご覧のとおり、$a1 と $a2 は明らかに 2 つの異なるオブジェクトです (オブジェクト識別子が異なります)。ただし、注意すべき点は、「b」が指すオブジェクト識別子が両方とも #2 であることです。これは、2 つのオブジェクトが同じであることを証明しています。これが「浅いコピー」の「欠陥」ですが、これら 2 つのオブジェクトには必要な場合があります。同様に、PHP のクローンもデフォルトで「浅いコピー」になります。
なぜ浅いコピーと呼ばれるのでしょうか?
コピーする際はすべての属性が「値渡し」であり、上記の b 属性にはオブジェクト識別子が格納されるため、「参照渡し」と同等になります。これは完全なコピーではないため、「浅いコピー」と呼ばれます。 。
ディープコピー
上で述べたように、 clone キーワードを使用すると、古いオブジェクトの __clone() メソッドが自動的に呼び出されます (その後、コピーされたオブジェクトが返されます)。そのため、対応するクラスの __clone() メソッドを書き換えるだけで済みます。返されるオブジェクトの「参照渡し」プロパティが別の新しいオブジェクトを指すようにします。以下は例です (実際には __clone() を書き直すためにさらに多くの手順が必要となる「浅いコピー」の例と比較できます):
結果は異なります。b 属性のオブジェクト識別子に注意してください: