perlのClass::Accessor的なもの。

ちょっと探したけど、見当たらなかったので書いてみた。

abstract class Accessor {
	protected function __call($name,$params) {
		if (preg_match('/(set|get)(_)?/',$name)) {
			$prefix = substr($name,0,3);
			$_name = strtolower(preg_replace('/^(set|get)(_)?/','',$name));
			if (!property_exists($this, $_name)) 
				throw new Exception("Tried to $prefix $_name. " . get_class($this) . "::$name");
			switch($prefix) {
				case 'set':
					$this->{$_name} = array_pop($params);
					return true;
				case 'get':
					return $this->{$_name};
			}
		}
		return false;
	}
}

使い方はこんな感じ。

class TestOverLoad extends Accessor {
	protected $foo;
	protected $bar;
	private $hage;
	public function getHage(){
		return $this->hage;
	}
	public function setHage($hage) {
		$this->hage = $hage;
	}
	public function getClass(){
		return __CLASS__;
	}
}

$hoge = new TestOverLoad();
echo $hoge->getClass() . PHP_EOL;
$hoge->setFoo("aa");
$hoge->setBar("bb");
$hoge->setHage("cc");
echo $hoge->getFoo() . PHP_EOL;
echo $hoge->getBar() . PHP_EOL;
echo $hoge->getHage() . PHP_EOL;

privateメンバには対応できてないので、なんというか、中途半端。Javaのreflectionみたいに、こういうときに何とかできる技無いのかなあ。
あと、__callをpublicにしようが、protectedにしようが、privateにしようが、動くの何でだ?
凄く気持ち悪いんだけど…。