[PHP-users 10601] Re: 1つのインスタンスを参照する2つの変数のチェック方法
WADA Masashi
php-users@php.gr.jp
Mon, 07 Oct 2002 14:44:06 +0900
和田です。
KUROSAWA Akira wrote:
>1つのインスタンスを参照する2つの変数(リファレンス)がある場合に
>この2つの変数が同じインスタンスを参照している事を確認する方法
>を探しています。
>
>例えば下記の「check_ref」のような関数を作りたいのです。
>
><?php
>class Hoge
>{
> var $hoge = 'abc';
>}
>
>$object1 =& new Hoge;
>$object2 =& new Hoge;
>
>$object1_ref =& $object1;
>
>if (check_ref($object1, $object2)) {
> // ここは実行されません
>}
>
>if (check_ref($object1, $object1_ref)) {
> // ここは実行されます
>}
>?>
石を投げられそうな思いつきですが・・・。
----------------------------------------
<?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() の代わりに、自前でグローバルカウンタを用意す
るとか・・・。)
>PHPマニュアルの『第15章 リファレンスの説明』
>http://www.php.net/manual/ja/language.references.php
>
>のページで「check_reference」と言うそのものズバリのロジックが紹介されて
>いましたが、この方法を応用したとしても、引数として渡すオブジェクトに対し
>て次のような制限が発生してしまいます。
上記のcheck_reference()は、なかなかトリッキーな解決策に見えま
した。言語仕様として判別方法が用意されていないのであれば、不本意
な解決策しか見つかりそうにないですね。
しかしリファレンスかどうかを判定できたとしても、プログラマがソー
スコードを見て期待する本来のリファレンスかどうかは区別できないの
ではないでしょうか? というのは、PHP4が高速化のため次のような特
徴を持っているからです。
上記の 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)。
----
和田雅志 (WADA Masashi)
wada@hh.iij4u.or.jp