前々からPHPで思っていた事なんですが、クラス単位でメソッドが実行された場合にフィルターをかけたいなーとか思っていたんですね。
例えばこのメソッドを先に実行してないと他のメソッドは絶対に実行したくないとか。結構そういうケースってあると思うんですよね。
今回の条件の場合は、Hogeクラスのinitが実行されてないとHogeクラスの他のメソッドを実行しないって処理にしたい場合を想定しています。
つまり、Hoge::$initがtrueの時のみmethod1〜method3やprivateMethodやprotectedMethodが実行される感じです。
こんな感じのコードです。
実行したいクラスとMethodFilterを継承したクラス(Hoge.php)
<?php
require 'MethodFilter.php';
class Hoge
{
private $isInit = false;
public function init() {
// 何らかの処理...
$this->isInit = true;
}
public function isInit() {
// initメソッドが実行されているか確認する
return $this->isInit;
}
public function method1() {
echo "execute method 1";
}
public function method2() {
echo "execute method 2";
}
private function privateMethod() {
echo "execute private method";
}
protected function protectedMethod() {
echo "execute protected method";
}
}
class HogeFilter extends MethodFilter
{
protected function callPreFilter($name, $arguments) {
if ($name == 'init') return null;
if (! $this->object->isInit()) {
throw new Exception("no execute init method");
}
}
protected function callPostFilter($name, $arguments, $return) {
if ($name == 'init') return $return;
echo "\n";
return $return;
}
}
実際の使い方はこんな感じです。
main.php
<?php
require "Hoge.php";
$object = new HogeFilter(new Hoge());
$object->init();
// initが実行されている時のみ実行される
$object->method1();
// initしてないとexecptionをthowする
$object2 = new HogeFilter(new Hoge());
try {
$object2->method1();
} catch (Exception $e) {
echo $e->getMessage()."\n";
}
// privateやprotectedなメソッドだって実行できるよ!
$object3 = new HogeFilter(new Hoge());
$object3->init();
$object3->isExecuteProtectMethod = true;
$object3->privateMethod();
$object3->protectedMethod();
実行結果
polidog$ php main.php
execute method 1
no execute init method
execute private method
execute protected method
クラス単位というかインスタンス単位でフィルターを使いたいときにめっちゃ便利だと思います!