装饰通用控制器动作

Decorate general controller actions

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

像这样:

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

我想自动扩展到一些 class 或类似的东西。

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

class HomeController extends ControllerDecorator
{
    public function indexAction() 
    {
         someLogicInThere();
         ...
    }
}

顺便说一句:记录器的东西并不重要。我的问题更多是设计模式问题

有什么好主意吗?

您可以在 ControllerDecorator 中使用内置方法 beforeAction (http://www.yiiframework.com/doc/api/1.1/CController#beforeAction-detail) and afterAction (http://www.yiiframework.com/doc/api/1.1/CController#afterAction-detail)。 这样你就可以装饰每个 class tha extends ControllerDecorator.

ps:我假设您使用的是 Yii。对吗?

你的问题叫做Cross-cutting concern. One way to handle this is by Aspect-oriented programming

你可以在 PHP >= 5.4 中用 Traits:

伪造这个
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();

作为一项实验,我已经自动化了这个编写基础的过程 class:

https://github.com/bitworking/AOP

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

最好研究一下解析文档类型并缓存新创建的 AOP 框架 class。 未测试:

http://go.aopphp.com/

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

另一种处理横切问题的方法是使用event driven programming。这不像 AOP 那样将它 100% 分离,但它是一种更受认可的设计模式,尤其是在 PHP.