装饰一般控制器动作

时间:2015-01-08 14:53:25

标签: php design-patterns decorator

我想装饰我项目中的每个控制器动作。 我想启动一个自定义记录器引擎,并在每次调用一个动作方法时停止它。

像这样:

class HomeController
{
    public function indexAction() 
    {
         Logger:start();
         someLogicInThere();
         ...
         Logger:end();
    }
}

我想自动延伸到某个类或类似的东西。

我的最终班级控制器将如下所示:

class HomeController extends ControllerDecorator
{
    public function indexAction() 
    {
         someLogicInThere();
         ...
    }
}
BTW:记录器的东西并不重要。我的问题更多的是设计模式问题

有什么好主意吗?

2 个答案:

答案 0 :(得分:0)

您可以在ControllerDecorator中使用beforeAction(http://www.yiiframework.com/doc/api/1.1/CController#beforeAction-detail)和afterAction(http://www.yiiframework.com/doc/api/1.1/CController#afterAction-detail)之类的内置方法。 通过这种方式,您可以装饰每个扩展ControllerDecorator的类。

ps:我假设你正在使用Yii。正确?

答案 1 :(得分:0)

您的问题称为Cross-cutting concern。处理此问题的一种方法是Aspect-oriented programming

您可以使用Traits

在PHP> = 5.4中伪造此内容
trait Logger
{
    public function indexAction()
    {
        echo 'logging before<br>';

        parent::indexAction();

        echo 'logging after<br>';
    }
}

class HomeControllerBase
{
    public function indexAction()
    {
         echo 'indexAction<br>';
    }
}

class HomeController extends HomeControllerBase
{
    use Logger;
}

$homeController = new HomeController();
$homeController->indexAction();

作为一项实验,我已经自动完成了编写基类的过程:

https://github.com/bitworking/AOP

我不会在生产中使用它,因为它需要很多资源。

更好地了解AOP框架,它解析doctype并缓存新创建的类。 未经测试:

http://go.aopphp.com/

https://github.com/AOP-PHP/AOP

处理横切问题的另一种方法是使用event driven programming。这并不是像AOP那样100%分开它,但它是一个更加认可的设计模式,特别是在PHP中。