スレッド表示 | フラット表示〕 全トピック 920 件中 103 番目 次≫ ≪前

オブジェクトについて

created: 2007-07-28 17:10 | modified: 2007-07-30 16:50 | reply: 3

[3828] オブジェクトについて

user: volks | created: 2007-07-28 17:10
いつもお世話になっております。
volksです。

オブジェクトの扱い方?で挙動が変わる事があって原因がつかめない事があります。テストをしてみて現象を再現してみたのですが、やはりどうなっているのか検討がつきませんでした。もしよろしければ、アドバイス頂ければと思います。

以下のサンプル1と2のコードですが、私は同じ出力結果を出すと考えて作成したのですが、結果は違いました。
$オブジェクト['○○○']
という使い方についての事になるかと思うのですが、アドバイスお願いできますでしょうか。


-------------------------------------------------
サンプル1
-------------------------------------------------

<?php
class Test{
var $name;

function setName($name) {
$this->name = $name;
}
}

class Info{
var $tObj;

function setClass(){
$tObj['member01'] = new Test();
$tObj['member01']->setName('yamada');
$this->tObj = $tObj;
}

function editName4Member01($name){
$Copy = $this->tObj;
$Copy['member01']->setName($name);
print 2;
print_r($Copy['member01']);
}

function getObj(){
return $this->tObj;
}
}

$Obj = new Info();
$Obj->setClass();

//出力
$names = $Obj->getObj();
print 1;
print_r($names);

$Obj->editName4Member01('sato');


//出力
$names = $Obj->getObj();
print 3;
print_r($names);

?>
-------------------------------------------------
サンプル1出力結果
-------------------------------------------------
1Array
(
[member01] => test Object
(
[name] => yamada
)

)
2test Object
(
[name] => sato
)
3Array
(
[member01] => test Object
(
[name] => sato
)

)

-------------------------------------------------
サンプル2
-------------------------------------------------

<?php
class Test{
var $name;

function setName($name) {
$this->name = $name;
}
}

class Info{
var $tObj;

function setClass(){
$tObj['member01'] = new Test();
$tObj['member01']->setName('yamada');
$this->tObj = $tObj;
}

function editName4Member01($name){
$Copy = $this->tObj['member01'];
$Copy->setName($name);
print 2;
print_r($Copy);
}

function getObj(){
return $this->tObj;
}
}


$Obj = new Info();
$Obj->setClass();

//出力
$names = $Obj->getObj();
print 1;
print_r($names);

$Obj->editName4Member01('sato');


//出力
$names = $Obj->getObj();
print 3;
print_r($names);

?>
-------------------------------------------------
サンプル2出力結果
-------------------------------------------------

1Array
(
[member01] => test Object
(
[name] => yamada
)

)
2test Object
(
[name] => sato
)
3Array
(
[member01] => test Object
(
[name] => yamada
)

)
-------------------------------------------------
reply: 3829 返信 編集 削除

[3829] 追記です。

user: volks | created: 2007-07-28 17:17
すいません、説明不足でした。

phpのバージョンは4.3.11になります。
私の予想では、ともにサンプル2の出力結果になると思っていました。

サンプル1ではコピーしたオブジェクトのプロパティを変更したつもりが、コピー元のオブジェクトにまで変更がかかってしまってる点がわかりません。

どうぞよろしくお願いします。
Parent: 3828  reply: 3832 返信 編集 削除

[3832] 連想配列とインスタンス

user: ゆうじ | created: 2007-07-29 17:44
こんにちは。

私もどちらもサンプル2だと思いましたが
PHP4.4.7でやってみたところvolksさんと同じ結果でした。

違いと言えば、
editName4Member01() ではじめに行ったコピーですね。

▼インスタンスをコピー
$Copy = $this->tObj['member01'];

▼配列をコピー
$Copy = $this->tObj;

至る所 $tObj を var_dump で見てみると、
配列上のオブジェクト test は、
はじめからリファレンスですね。

$Obj = new Info();
$Obj->setClass();
var_dump($Obj);
var_dump($Obj->tObj['member01']);

object(info)(1) {
["tObj"]=>
array(1) {
["member01"]=>
&object(test)(1) {
["name"]=>
string(6) "yamada"
}
}
}
object(test)(1) {
["name"]=>
string(6) "yamada"
}

インスタンスのコピーでは
値の $this->tObj['member01'] をコピーしてるので
結果は新しいインスタンス。

これに対し配列をコピーすると、
配列の持つリファレンスをコピーすることになるので、
コピー先も同じくリファレンスとなるみたい。

コピーしたものが違うので、
こんな現象になったと推測します。


でも、配列上に生成したオブジェクトが
連想配列から見るとリファレンスになるというのが
いまひとつふに落ちない仕様です。
これは、こういうものなのか、おかしいのか、わかりません。
Parent: 3829  reply: 3834 返信 編集 削除

[3834] 有難うございます

user: volks | created: 2007-07-30 16:50
ゆうじさんいつも有難うございます。

配列上に生成したオブジェクトは初めからリファレンスだったのですね。
私の調査不足でした。勉強になりました。

根本の原因の箇所が判明してすっきりしました。
有難うございました。
Parent: 3832  返信 編集 削除
スレッド表示 | フラット表示〕 全トピック 920 件中 103 番目 次≫ ≪前
ページの一番上へ
Googleグックマークに登録 Yahooグックマークに登録 livedoorクリップに登録 @niftyクリップに登録 はてなブックマークに登録 deliciousに登録 Buzzurlに登録 FC2ブックマークに登録
最近更新された掲示板トピックス
管理人Blog
Yahoo Search

最近更新したNote
PHPマニュアル
今日のブックマーク
PHPマニュアル関数検索
関数名を入力し検索ボタンをクリック↑