[PHP-users 10602] Re: 1つのインスタンスを参照する2つの変数のチェック方法

KUROSAWA Akira php-users@php.gr.jp
Mon, 07 Oct 2002 16:45:08 +0900


黒澤です。

WADA Masashi wrote:
>  和田です。

返信ありがとうございます。

#なかなかRESが付かなくて、ちょっとササクレてました(^^;

> KUROSAWA Akira wrote:
> 
>>1つのインスタンスを参照する2つの変数(リファレンス)がある場合に
>>この2つの変数が同じインスタンスを参照している事を確認する方法
>>を探しています。
(削除)
> 
>  石を投げられそうな思いつきですが・・・。

いえいえ、そんなことありません。
参考になりました。

> ----------------------------------------
> <?php
> 
> class _Object
> {
>     var $_object_id;
>     function _Object() {
>         $this->_object_id = uniqid("", TRUE);
>     }
>     function is_equals($obj) {
>         return ($this->_object_id == $obj->_object_id);
>     }
> }
> 
> class Hoge extends _Object
> {
>     var $hoge = 'abc';
> }
> 
> $object1 =& new Hoge;
> $object2 =& new Hoge;
> $object1_ref =& $object1;
> 
> if ($object1->is_equals($object2)) {
>     // ここは実行されません
> }
> if ($object1->is_equals($object1_ref)) {
>     // ここは実行されます
> }
> 
> ?>
> ----------------------------------------
> 
> 問題は uniqid() がどれだけユニーク性を保証してくれるのか、です。
> (もしくは uniqid() の代わりに、自前でグローバルカウンタを用意す
> るとか・・・。)

オブジェクトIDを自分で管理する構想は漠然と持ってはいたのですが
和田さんが具体的なコードにしてくれたおかげで、ふん切りが付きました(^^
自前のグローバルカウンタを使う方法で再考してみます。
ありがとうございました。

>>PHPマニュアルの『第15章 リファレンスの説明』
>>http://www.php.net/manual/ja/language.references.php
>>
>>のページで「check_reference」と言うそのものズバリのロジックが紹介されて
>>いましたが、この方法を応用したとしても、引数として渡すオブジェクトに対し
>>て次のような制限が発生してしまいます。
> 
>  上記のcheck_reference()は、なかなかトリッキーな解決策に見えま
> した。言語仕様として判別方法が用意されていないのであれば、不本意
> な解決策しか見つかりそうにないですね。

オブジェクトIDを自分で管理する方法は許容範囲内だと思います。(^^

check_referernce()は引数で渡されたリファレンスを関数内部でコピーして
います。この時点でオブジェクト指向的にはアウトだと思いました。
関数の実行前と実行後では引数で渡したインスタンスが物理的に別の
インスタンスになっているからです。

オブジェクトのインスタンスではなく、通常の変数であれば、これでもOK
なんですけどね。

>  しかしリファレンスかどうかを判定できたとしても、プログラマがソー
> スコードを見て期待する本来のリファレンスかどうかは区別できないの
> ではないでしょうか? というのは、PHP4が高速化のため次のような特
> 徴を持っているからです。

今回のケースでは「ソースコードを見て区別できる」必要はありません。
あくまでも、実行時に確実に判定できればOKです。

> 上記の check_reference() を利用した次のコードを実行してみると、
> 
> $a = 1;
> $b = $a;
> print "$a, $b : ".(check_reference($a, $b) ? "ref.\n" : "not ref.\n");
> $a = 2;
> print "$a, $b : ".(check_reference($a, $b) ? "ref.\n" : "not ref.\n");
> 
> 結果は
> 
> 1, 1 : ref.
> 2, 1 : not ref.
> 
> となります(テスト環境はPHP4.1.2/4.2.2)。

多分、タイプミスだと思うんですが、2行目の「$b = $a」は「$b =& $a」ですよね。
だとすれば、これは期待通りの動作です。

申し訳ありませんが、和田さんの言われる「高速化のための特徴」と言うのが
うまく読み取れませんでした。
もしよろしければ、追加の説明を頂けるとありがたいのですが。
よろしくお願いします。

#「リファレンスの同一インスタンス判定ロジック」については
#完成次第、こちらで報告させて頂く予定です。

-- 
株式会社システムジェイ
    システム開発グループ
    黒澤 明  kurosawa@systemj.com