web-dev-qa-db-ja.com

PHPでのオブジェクトのコピーとクローン

以下を検討してください。

$object1 = new stdClass();
$object2 = $object1;
$object3 = clone $object1;

$object1->content = 'Ciao';

var_dump($object1);
 // Outputs object(stdClass)#1 (1) { ["content"]=> string(4) "Ciao" }
var_dump($object2);
 // Outputs object(stdClass)#1 (1) { ["content"]=> string(4) "Ciao" }
var_dump($object3);
 // Outputs object(stdClass)#2 (0) { }

PHP $object2$object1と同じ内容を持っているという動作は正常ですか?

私には、$object2はコピーではなく$object1への参照であるように思えます。コンテンツを変更する前にオブジェクトを複製すると、コピーのように機能します。この動作は変数で発生する動作とは異なり、私には直感的ではないようです。

27
ddamasceno

はい、それは正常です。オブジェクトは常にPHP5で参照によって「割り当てられます」。オブジェクトのコピーを実際に作成するには、オブジェクトをcloneする必要があります。

より正確にするために、引用してみましょう マニュアル

PHP5以降、オブジェクト変数にはオブジェクト自体が値として含まれなくなりました。これには、オブジェクトアクセサーが実際のオブジェクトを検索できるようにするオブジェクト識別子のみが含まれます。オブジェクトが引数で送信されたり、返されたり、別の変数に割り当てられたりすると、異なる変数はエイリアスではなく、同じオブジェクトを指す識別子のコピーを保持します。

39
deceze

それは正常であり、私はこれを直感的ではないと考えません(オブジェクトインスタンスの場合):

$object1 = new stdClass();

新しいオブジェクトインスタンスを$object1に割り当てます。

$object2 = $object1;

オブジェクトインスタンスを$object2に割り当てます。

$object3 = clone $object1;

既存のオブジェクトインスタンスから複製された新しいオブジェクトインスタンスを$object3に割り当てます。

そうでない場合は、具象オブジェクトインスタンスを渡す必要があるたびに、参照で渡す必要があります。これは少なくとも負担になりますが、PHPはバージョン4でそうでした(比較 zend.ze1_compatibility_mode core )。これは役に立ちませんでした。

オブジェクトのコピー方法をオブジェクトで指定できるようにするクローン

13
hakre

オブジェクトコピーvsオブジェクトクローン

class test{
public $name;
public $addr;
}
// i create a object $ob
$ob=new test();

// object copy 

$ob2=$ob;

// in object copy both object will represent same memory address 
// example 
$ob->name='pankaj raghuwanshi';

// i am printing second object
echo $ob2->name;
// output is : pankaj raghuwanshi

// another example 

$ob2->name='raghuwanshi pankaj';
echo $ob->name;
// output is :  raghuwanshi pankaj

// it means in copy of object original and copy object share same memory place

オブジェクトのクローン

$ob1=clone $ob;

echo $ob1->name;  // output is :  raghuwanshi pankaj
echo $ob->name;   // output is :  raghuwanshi pankaj

 $ob1->name='PHP Clone';
 $ob->name='PHP Obj';

echo $ob1->name;  // output is :  PHP Clone
echo $ob->name;   // output is :  PHP Obj

// on the base of these output we can say both object have their own memory space 
// both are independent 
9
PankajR

Php5のオブジェクトは基本的にポインタです。つまり、オブジェクト変数には、他の場所にあるオブジェクトデータのアドレスのみが含まれています。仕事、宿題 $obj1 = $obj2はこのアドレスのみをコピーし、データ自体には触れません。これは確かに直観に反するように見えるかもしれませんが、実際には非常に実用的です。 php配列が同じセマンティクスを使用したいと思います。

4
user187291