Herosphp的生命周期

在说AOP编程之前,先说下herosphp中app请求的生命周期,我们大致为WebAPplication设计了4个生命周期:

请求初始化其实就是从URL中解析提取出{module}, {action}, {method}

然后再根据{module}, {action}, {method}找到对应的Controller文件;

然后再调用对应的{method},完了之后再发送响应。当然响应的过程中肯定是要顺带着解析下模板标签啦。

恩,这就完了,貌似感觉很简单啊。

生命周期切面

切面(AOP)是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。再Herosphp中我们提供了4个节点来让你插入切面。分别是:

  1. beforeRequestInit : 请求初始化之前
  2. beforeActionInvoke : 控制器方法调用之前
  3. beforeSendResponse : 响应发送之前
  4. afterSendResponse : 响应发送之后

配置切面类

在3.0的版本中,我们提供了更加灵活的切面设置。我们提供了一个全局的生命周期监听器 modules/DefaultWebappListener, 它能拦截所有的请求,考虑到你在特定的模块可能需要增加特殊的监听器(比如是后台的模块你肯定需要一个切面拦截进行权限判断)。我们为每个模块都单独设置了监听器 ModuleListener 供模块切面监听。

编写切面代码

在切面配置好了之后,你就可以愉快的使用切面了,上面说道,我们提供了4个节点供你插入切面:

<?php

namespace app;

use herosphp\core\WebApplication;
use herosphp\http\HttpRequest;
use herosphp\listener\IWebAplicationListener;
use herosphp\listener\WebApplicationListenerMatcher;

/**
 * 应用程序默认生命周期监听器
 * @author yangjian<yangjian102621@gmail.com>
 */
 class DefaultWebappListener extends WebApplicationListenerMatcher implements IWebAplicationListener {

     /**
      * 请求初始化之前
      * @return mixed
      */
     public function beforeRequestInit()
     {
         // TODO: Implement beforeRequestInit() method.
     }

     /**
      * action 方法调用之前
      * @return mixed
      */
     public function beforeActionInvoke(HttpRequest $request)
     {

     }

     /**
      * 响应发送之前
      * @return mixed
      */
     public function beforeSendResponse(HttpRequest $request, $actionInstance)
     {
         $webApp = WebApplication::getInstance();
         //注册当前app的配置信息
         $actionInstance->assign('appConfigs', $webApp->getConfigs());
         $actionInstance->assign('params', $webApp->getHttpRequest()->getParameters());
     }

     /**
      * 响应发送之后
      * @return mixed
      */
     public function afterSendResponse($actionInstance)
     {
         // TODO: Implement afterSendResponse() method.
     }

}

新增的实现必须继承抽象类WebApplicationListenerMatcher, 并实现接口 IWebAplicationListener.

设置AOP请求过滤(@since v3.0.1)

在实际开发中,你可能会遇到这样情况,比如你想在后台模块拦截请求来做登录认证或者权限认证,这个时候你的最佳做法应该是在 admin 模块的 ModuleListener 的 beforeActionInvoke 做权限认证的。但是有部分页面的你是想跳过验证的,比如说登录页面,在 v3.0.1 版本之前,你需要自己在每个切面去做判断,跳过。v3.0.1 新增了 skipUrl() 接口,可以轻松帮你实现请求过滤。

class DefaultWebappListener extends WebApplicationListenerMatcher implements IWebAplicationListener {

     /**
      * 请求初始化之前
      * @return mixed
      */
     public function beforeRequestInit()
     {
         //设置跳过监听的uri, 比如登录页面,注册页面等
         $this->skipUrl("/user/**"); //跳过用户模块下所有请求
         $this->skipUrl("/admin/login/**"); //跳过登录控制器所有请求
         $this->skipUrl("/admin/scode/index"); //跳过验证码请求

         // TODO: Implement beforeRequestInit() method.
     }

     /**
      * action 方法调用之前
      * @return mixed
      */
     public function beforeActionInvoke(HttpRequest $request)
     {
        echo "捕获请求";
     }

     /**
      * 响应发送之前
      * @return mixed
      */
     public function beforeSendResponse(HttpRequest $request, $actionInstance)
     {
         $webApp = WebApplication::getInstance();
         //注册当前app的配置信息
         $actionInstance->assign('appConfigs', $webApp->getConfigs());
         $actionInstance->assign('params', $webApp->getHttpRequest()->getParameters());
     }

     /**
      * 响应发送之后
      * @return mixed
      */
     public function afterSendResponse($actionInstance)
     {
         // TODO: Implement afterSendResponse() method.
     }

}

切面有什么(卵)用?

这个问题问的好,有了切面你可以,很随意的应用程序的各个声明周期插入你的代码,而又不影响这个程序的结构,实现一个松散的耦合。比如说,产品那边需要你实现这样一个需求,如果是手机访问就立马调到手机站。这个是时候当然你有很多方案,比如你可能会想到在框架的统一入口去更改代码,或者去基类Controller的构造方法去插入一段代码,但是显然那些方法都影响到你整个应用程序的结构和生命周期了,他们都不如切面那么可爱。

二次开发

如果想对app的生命周期和切面进行二次开发或者重构,请重点阅读以下几个类和接口就可以了:

  • herosphp/core/WebAPplication
  • herosphp/listener/IWebAplicationListener
  • herosphp/listener/WebApplicationListenerMatcher
Copyright © HerosPHP 2016 all right reserved,powered by Gitbook最后更新时间: 2017-09-07 16:51:14

results matching ""

    No results matching ""