[myclabs/deep-copy]「オブジェクトの複製」には本質的に厄介な問題をいくつも含みます。オブジェクトの再帰的な複製(ディープコピー)には直感的ではない動作や単純ではない依存関係が発生しがちです。myclabs/deep-copyはそれをいい感じに解決してくれます。(2017-04-12)インストールComposerでインストール可能です。文字列および配列を含む全てのPHPの値と変数はコピーオンライト(CoW)と呼ばれる最適化戦略がとられます。$aが実行された状態では両者は同じ配列ですが、破壊的操作を行ったタイミングで別々の道を歩み始めます。二つの配列を複製したければ、PHPでは別の変数に代入してやるだけで十分なのです。Rubyは、このような振舞はしません。trueこのように、Rubyでは単に別の変数に代入しただけでは値が複製されたことにはならず、終始において一蓮托生です。次に、stdClassを使ってオブジェクトのコピーについて実験してみます。bool(true)配列と同じようにやったつもりですが、違った結果になりました。$obj;のようにcloneキーワードを用ゐる必要があります。Manualに説明があります。再帰的なオブジェクトのコピーここまででオブジェクトの複製について基本的な理解が得られたところで、ここからはGitHubのmyclabs/DeepCopyのREADMEから画像を拝借しつつ説明を進めていきます。アルファベット1文字のクラスでとてもわかりにくいのですが、以下のようなクラスがあったとします。}}これらのクラスを使ってコードを書いてみますね。$b;これをグラフにすると以下のような状態です。次に、これを「まるごと」複製してみたいと思ったとします。まるごと複製とは、ここでは$aを$a2に複製したとして、$a2->cのオブジェクトを変更したとしても$a->cのオブジェクトには反映されたくないといふことだとします。$a->bについても同様。$a2->c-nameに別の文字列を入れてみたらどうかな。}$a->cの方も変っちゃったよだめじゃん...これはグラフにすると以下のような状態です。Manualを参考に__clone()マジックメソッドを定義してみることにします。クラス定義ですが、変更点は__clone()が増えてるだけです。}今度は$a->cと$a2->cの状態はきっちり切り離せたようです。今度は$a->cと$a->b->cの関係が奇妙なことになってしまひましたね。やれやれ...myclabs/deep-copyの出番だ__clone()では問題が解決しないことがわかったので、クラス定義は元の状態に戻します。}やった、ばっちりだ!このライブラリは利用すべきなの?オブジェクトの複製にどのような手法をとるのが望ましいかは、場合によります。そもそも再帰的な複製(ディープコピー)は必要なく、浅い複製(シャローコピー)で十分だといふケースもあります。myclabs/deep-copyは直感に反しないディープコピーの手法として、良い選択肢のひとつです。上記のようなオブジェクトの複製に伴った理窟がいまひとつ理解できない場合は、オブジェクトの利用を諦めて連想配列に落としてみるといったこともPHPらしい、割り切った解決法ではあります。筆者が業務として開発に携るpixiv.netでは、オブジェクトはほとんど利用しません。2017ピクシブ開発基盤チームのうさみ(@tadsan)です。(1)はてなブログをはじめよう!zonu_exeさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。