class に public な変数(プロパティ)を定義することは、オブジェクト指
向のカプセル化の観点から論外ですが、private なプロパティを定義して、
get_プロパティ名(), set_プロパティ名() とかを作るのもイケてなかった
のですね。(薄々気づいてはいましたが…。)
PHP には __get() と __set() という特殊メソッドがあります。
例えば
$myclass = new MyClass;
$myclass->hoge = 1;
の場合、定義していれば MyClass::__set() が呼ばれます。
以下のように private なプロパティを定義し、__get(), __set() を介し
てアクセス制御すると良いでしょう。このプロパティは読み取り専用、こ
のプロパティは両方大丈夫とか。
class Post {
private $title;
private $content;
private $author;
private $comments;
private $_getters = array('title', 'content', 'author', 'comments');
private $_setters = array('title', 'content', 'author');
public function __get($property) {
if(in_array($property, $this->_getters)) {
return $this->$property;
}
if(in_array($property, $this->_setters)) {
throw new Exception('Property "' . $property . '" is write-only.');
}
throw new Exception('Property "' . $property . '" is not accessible.');
}
public function __set($property, $value) {
if(in_array($property, $this->_setters)) {
$this->$property = $value;
return;
}
if(in_array($property, $this->_getters)) {
throw new Exception('Property "' . $property . '" is read-only.');
}
throw new Exception('Property "' . $property . '" is not accessible.');
}
}
$post = new Post;
$post->title = "タイトルだよ〜ん\n";
//=> エラーが発生することなく、代入できる。
print_r($post->title);
//=> エラーが発生することなく、「タイトルだよ〜ん」と表示される。
$post->comments = "コメントだよ〜ん\n";
//=> エラーが発生することなく、代入できる。
print_r($post->comments);
//=> 例外が発生する。PHP Fatal error: Uncaught exception 'Exception' with message 'Property "comments" is read-only.'
プロパティによっては、加工してから get/set したいものもあるかもしれ
ません。その場合も __get(), __set() を拡張すれば良いです。PHP マニュ
アルのオーバーロードの項
が参考になると思います。ただし、今回参考に
したコード
は間違っているので、注意が必要です。。。
PHP 5.4 からは trait が使えるので、trait 化して自作の各 class に組
み込むと良いと思います(まだ環境を作ってないので、未確認..)。