FrontPage  Index  Search  Changes  RSS  Login

[php]オブジェクトの複製

複製する

PHP5では、オブジェクトはリファレンスとして扱われます。これはつまり、代入操作によって他変数にオブジェクトをコピーした場合は、両変数が指すオブジェクトが同一である事を意味します。

オブジェクト内の一部メンバを共有しながら、他メンバを独立させたい場合、cloneキーワードを利用してオブジェクトを複製する事が出来ます。

cloneキーワードによる複製の際、__cloneメソッドが呼び出されます。__cloneメソッドをクラス内で再定義(オーバーロード)する事で、複製操作をコントロールする事が可能になります。デフォルトでは、参照変数はそのまま同一アドレスを参照し、値変数は同値を渡して別アドレスを参照するようになります。

コード例

__cloneメソッドをオーバーロードせずに、デフォルトの挙動を見る事にします。

まず、クラス内に参照変数と値変数を用意します。これらについて、代入演算子によるコピーとcloneによる複製との違いを確認します。

代入演算子によってコピーされた場合、2つの変数が指すオブジェクトが同一である事に対し、cloneによって複製された場合、参照変数以外のメンバは独立している事から(一部を共有する)別オブジェクトである事が分かります。

<?php

class Sample
{

    static $_share = 0;
    public $ident;

    public function __construct()
    {
        self::$_share++;
        $this->ident = uniqid();
    }

    private function __set($dist, $value)
    {
        self::$_share = $value;
    }

    private function __get($dist)
    {
        return self::$_share;
    }

}

$objA1 = new Sample();
$objA2 = $objA1;
$objB  = clone $objA1;
echo "---- setup ----\n";
echo "objA1:\n";
echo "  share = {$objA1->share}\n";
echo "  ident = {$objA1->ident}\n";
echo "objA2:\n";
echo "  share = {$objA2->share}\n";
echo "  ident = {$objA2->ident}\n";
echo "objB:\n";
echo "  share = {$objB->share}\n";
echo "  ident = {$objB->ident}\n";
echo "\n";

$objA1->share = 100;
echo "---- set objA1::share = 100 ----\n";
echo "objA1:\n";
echo "  share = {$objA1->share}\n";
echo "  ident = {$objA1->ident}\n";
echo "objA2:\n";
echo "  share = {$objA2->share}\n";
echo "  ident = {$objA2->ident}\n";
echo "objB:\n";
echo "  share = {$objB->share}\n";
echo "  ident = {$objB->ident}\n";
echo "\n";

$objA2->ident = 0;
echo "---- set objA2::identifier = 0 ----\n";
echo "objA1:\n";
echo "  share = {$objA1->share}\n";
echo "  ident = {$objA1->ident}\n";
echo "objA2:\n";
echo "  share = {$objA2->share}\n";
echo "  ident = {$objA2->ident}\n";
echo "objB:\n";
echo "  share = {$objB->share}\n";
echo "  ident = {$objB->ident}\n";
echo "\n";

$objB->ident = 10000;
echo "---- set objB::identifier = 10000 ----\n";
echo "objA1:\n";
echo "  share = {$objA1->share}\n";
echo "  ident = {$objA1->ident}\n";
echo "objA2:\n";
echo "  share = {$objA2->share}\n";
echo "  ident = {$objA2->ident}\n";
echo "objB:\n";
echo "  share = {$objB->share}\n";
echo "  ident = {$objB->ident}\n";
echo "\n";

?>
---- setup ----
objA1:
  share = 1
  ident = 45b0dcde3361f
objA2:
  share = 1
  ident = 45b0dcde3361f
objB:
  share = 1
  ident = 45b0dcde3361f

---- set objA1::share = 100 ----
objA1:
  share = 100
  ident = 45b0dcde3361f
objA2:
  share = 100
  ident = 45b0dcde3361f
objB:
  share = 100
  ident = 45b0dcde3361f

---- set objA2::identifier = 0 ----
objA1:
  share = 100
  ident = 0
objA2:
  share = 100
  ident = 0
objB:
  share = 100
  ident = 45b0dcde3361f

---- set objB::identifier = 10000 ----
objA1:
  share = 100
  ident = 0
objA2:
  share = 100
  ident = 0
objB:
  share = 100
  ident = 10000
Last modified:2007/01/20 00:18:13
Keyword(s):[php]
References:[PHPのページ]