PHPの__getメソッドではまったところ
PHPでハマったことがあったので書きます。常識的なことだったらすみません。。
__getメソッドとは
__getメソッドは存在しないプロパティへのアクセスがあったときに呼ばれます。
__getメソッドはPHPのオーバーロード機能の1つです。PHPのオーバーロード機能はプロパティやメソッドを動的に生成する機能で、Javaとかのメソッドのオーバーロードとは全然違いますのでご注意ください。
__getメソッドを使ったサンプルクラス
以下のようなクラスを作ります。
<?php class Sample { private $_array; public function __construct() { $this->_array = array(); $this->_array['test'] = 'hogehoge'; } public function __get($name) { if (isset($this->_array[$name]) === false) { throw new Exception("Sample::${name} is undefined."); } return $this->_array[$name]; } }
上記サンプルクラスでは存在しないプロパティへのアクセスがあった場合、__getメソッドが呼ばれ、プライベートプロパティの$_arrayの要素から取得するようになっています。
<? require_once 'sample.php'; $obj = new Sample(); echo $obj->test; // 出力> hogehoge
今回はまったところ
上記サンプルクラスをそのまま使います。下記のコードの実行結果はどうなるでしょうか?
<?php require_once 'sample.php'; $obj = new Sample(); if (empty($obj->test) === true) { echo 'empty!!'; } else { echo 'not empty'; }
上記コードを実行すると「empty!!」が出力されます。$obj->testは__getメソッドで動的に生成されているはずなのになんででしょうか。
原因:isset関数とempty関数のときは__issetメソッドが呼ばれているから
__isset() は、 isset() あるいは empty() をアクセス不能プロパティに対して実行したときに起動します。
PHP: オーバーロード - Manual
つまり存在しないプロパティをisset関数、empty関数の引数として渡すと__getメソッドではなく__issetメソッドが呼び出されます。上記サンプルクラスでは__issetメソッドが定義されていなかったのでisset関数、empty関数の引数として使われた場合$obj->testは常にfalseを返していたということです。
上記サンプルクラスを修正
__issetメソッドを定義します。これでisset関数、empty関数の引数の場合も$_arrayの要素から探すようになります。
<?php class Sample { private $_array; public function __construct() { $this->_array = array(); $this->_array['test'] = 'hogehoge'; } public function __get($name) { if (isset($this->_array[$name]) === false) { throw new Exception("Sample::${name} is undefined."); } return $this->_array[$name]; } public function __isset($name) { if (isset($this->_array[$name]) === false) { return false; } return $this->_array[$name]; } }
まとめ
__getメソッドを利用する場合は同時に__issetメソッドも定義しましょうー。
- 作者: Rasmus Lerdorf,Kevin Tatroe,Peter MacIntyre,高木正弘
- 出版社/メーカー: オライリー・ジャパン
- 発売日: 2007/10/23
- メディア: 大型本
- 購入: 16人 クリック: 317回
- この商品を含むブログ (48件) を見る