Help us understand the problem. What is going on with this article?

PHPのディープコピー

More than 1 year has passed since last update.

JavaScriptでディープコピーが必要になった際にPHPでのディープコピーが面倒だったことを思い出してのメモ(JavaScriptも一応メモ)

PHP

http://php.net/manual/ja/language.oop5.cloning.php

class SubObject
{
    static $instances = 0;
    public $instance;

    public function __construct() {
        $this->instance = ++self::$instances;
    }

    public function __clone() {
        $this->instance = ++self::$instances;
    }
}

class MyCloneable
{
    public $object1;
    public $object2;

    function __clone()
    {
        // this->object のコピーを作成します。こうしないと、
        // 同じオブジェクトを指すことになってしまいます。
        $this->object1 = clone $this->object1;
    }
}

$obj = new MyCloneable();

$obj->object1 = new SubObject();
$obj->object2 = new SubObject();

$obj2 = clone $obj;


print("元のオブジェクト\n");
print_r($obj);

print("クローンオブジェクト\n");
print_r($obj2);

PHPでオブジェクトをディープコピーをしようとすると
cloneではオブジェクト内の参照型のものはシャローコピーになるので
参照型のものについては公式のコードの上記のように__cloneを実装してcloneを使えば良いのですが、例えばそのオブジェクトの中に更に参照型があったりした場合もそれぞれに__cloneを実装して行かないといけないので面倒なのでした。

マニュアル通りに対応した後に見つけたのですが以下の方法が何も手を加えなくて良いので便利です。

$new_object = unserialize(serialize($object));

unserializeを使う際は以下に注意。
ユーザーからの入力をそのままunserialize()に渡してはいけません。
PHPのunserialize関数に外部由来の値を処理させると脆弱性の原因になる

JavaScript

  • jQueryを使う
var object = {省略};
var newObject = {};
$.extend(true, newObject, object);
// ObjectとArrayにのみ対応
  • lodash.jsを使う
var object = {省略};
var newObject = _.clone(object, true);
var object = {省略};
var newObject = _.cloneDeep(object);
  • JSONでのシリアライズは完全ではないようです

参考
http://qiita.com/seihmd/items/74fa9792d05278a2e898
http://qiita.com/knhr__/items/d7de463bf9013d5d3dc0

horikeso
個人的な備忘録ばかりですが、よろしくお願いします。難しいことはよくわかりません!
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away