以下を検討してください。
$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
への参照であるように思えます。コンテンツを変更する前にオブジェクトを複製すると、コピーのように機能します。この動作は変数で発生する動作とは異なり、私には直感的ではないようです。
はい、それは正常です。オブジェクトは常にPHP5で参照によって「割り当てられます」。オブジェクトのコピーを実際に作成するには、オブジェクトをclone
する必要があります。
より正確にするために、引用してみましょう マニュアル :
PHP5以降、オブジェクト変数にはオブジェクト自体が値として含まれなくなりました。これには、オブジェクトアクセサーが実際のオブジェクトを検索できるようにするオブジェクト識別子のみが含まれます。オブジェクトが引数で送信されたり、返されたり、別の変数に割り当てられたりすると、異なる変数はエイリアスではなく、同じオブジェクトを指す識別子のコピーを保持します。
それは正常であり、私はこれを直感的ではないと考えません(オブジェクトインスタンスの場合):
$object1 = new stdClass();
新しいオブジェクトインスタンスを$object1
に割り当てます。
$object2 = $object1;
オブジェクトインスタンスを$object2
に割り当てます。
$object3 = clone $object1;
既存のオブジェクトインスタンスから複製された新しいオブジェクトインスタンスを$object3
に割り当てます。
そうでない場合は、具象オブジェクトインスタンスを渡す必要があるたびに、参照で渡す必要があります。これは少なくとも負担になりますが、PHPはバージョン4でそうでした(比較 zend.ze1_compatibility_mode
core )。これは役に立ちませんでした。
オブジェクトコピー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
Php5のオブジェクトは基本的にポインタです。つまり、オブジェクト変数には、他の場所にあるオブジェクトデータのアドレスのみが含まれています。仕事、宿題 $obj1 = $obj2
はこのアドレスのみをコピーし、データ自体には触れません。これは確かに直観に反するように見えるかもしれませんが、実際には非常に実用的です。 php配列が同じセマンティクスを使用したいと思います。