問題点
PHPのマジックメソッド__isset
は,無限ループを防ぐために**「直前の呼び出しと同じ引数で呼ばれたら〜」**という条件で判定を行っているとみられる.そのため…
<?php
class Storage
{
public function __isset($key)
{
return isset($this->$key);
}
}
$s = new Storage;
var_dump(isset($s->p)); // bool(false)
これを以下のような実装に変えてしまうと無限ループを引き起こし,php.iniの設定によってはクラッシュすることもある.
<?php
class Storage
{
public function __isset($key)
{
return isset($this->{"_$key"});
}
}
$s = new Storage;
var_dump(isset($s->p)); // Segmentation Fault または Fatal Error
解決策
__isset
の実装の中で自分自身に対してプロパティの存在確認(とNULLチェック)を行いたい場合,property_exists
で代用する.
<?php
class Storage
{
public function __isset($key)
{
return property_exists($this, "_$key") && $this->{"_$key"} !== null;
}
}
$s = new Storage;
var_dump(isset($s->p)); // bool(false)