# 中间件

中间件主要用于编织从 请求(Request) 到 响应(Response) 的整个流程,该功能完全基于 PSR-15 实现。 通过在控制器中use Cml\Http\Message\MiddlewareControllerTrait;开启中间件支持,自动通过 PSR-17 实现的HTTP工厂注入 PSR-7RequestResponse

# 使用

  • # 入口文件添加绑定

//Psr17 http工厂
Cml::getContainer()->bind('psr17_http_factory', \Cml\Http\Message\HttpFactory::class);
//Psr15 RequestHandler
Cml::getContainer()->bind('psr15_request_handler', \Cml\Http\Message\RequestHandler::class);
//Psr7 ServerRequest
Cml::getContainer()->bind('psr7_server_request', \Cml\Http\Message\Psr\ServerRequest::class);
//Psr7 Response
Cml::getContainer()->bind('psr7_response', \Cml\Http\Message\Psr\Response::class);
  • # 控制器中开启支持

<?php
 namespace web\Controller;

 use Cml\Controller;
 use Cml\Http\Message\MiddlewareControllerTrait;

class DefaultController extends Controller
{
    //引入这个trait开启中间件支持
    use MiddlewareControllerTrait; 

    public function index()
    {
        //使用 $this->request 来处理请求
        $contentType = $this->request->getHeaderLine('accept');

        //使用  $this->response 来处理响应
        return $this->response->raw($contentType);
    }
}

# 中间件配置

# 全局加载的

在项目目录Config\middleware.php中配置

return [
    'global' => [
        \Cml\Middleware\Cors::class //所有请求都生效
    ],
    'app' => [
        'web/*' => \Cml\Middleware\CorsMiddleware::class //web/xxx下的所有请求都生效
    ],
    'controller' => [
        \web\Controller\HomeController::class =>  \Cml\Middleware\CorsMiddleware::class //HomeController的所有方法都生效
    ],
    'action' => [
        \web\Controller\HomeController::class.'@test' => \Cml\Middleware\CorsMiddleware::class //\web\Controller\HomeController::test方法生效
    ]
];

# 针对某个应用的如:web

项目目录/Application/web/Config/middleware.php中配置

return [
    'app' => [
        \Cml\Middleware\CorsMiddleware::class //当前应用下的所有控制器都生效
    ],
    'controller' => [
        \web\Controller\HomeController::class => \Cml\Middleware\CorsMiddleware::class //HomeController的所有方法都生效
    ],
    'action' => [
        \web\Controller\HomeController::class . '@test' => \Cml\Middleware\CorsMiddleware::class //\web\Controller\HomeController::test方法生效
    ]
];

# 在路由中定义中间件

Route::group('web', function() {
    Route::get('new', [\web\Controller\HomeController::class, 'test']);
    Route::get('v2', [\web\Controller\HomeController::class, 'test']);
}, [
    \Cml\Middleware\CorsMiddleware::class //针对group下的两个路由的中间件
]);

Route::get('web/v2', [\web\Controller\HomeController::class, 'test'], [
     \Cml\Middleware\CorsMiddleware::class //针对这个路由的中间件
]);

# 执行顺序

全局配置中配置的 global 中间件 => 全局配置中配置的针对app的中间件 => 应用配置中配置的针对app的中间件 => 全局配置中配置的针对控制器的中间件 => 应用配置中配置的针对控制器的中间件 => 全局配置中配置的针对action的中间件 => 应用配置中配置的针对action的中间件 => Route::group中配置的中间件 => Route::方法 配置的中间件

# 定义一个中间件

遵守 PSR-15 实现

<?php
namespace xxx;

use Cml\Http\Message\Request;
use Cml\Http\Message\Response;
use Cml\Interfaces\Middleware;
use Cml\Interfaces\RequestHandler;


/**
 * 演示
 *
 */
class TestMiddleware implements Middleware
{
    /**
     * 处理传入的服务器请求以产生相应
     *
     * @param Request $request
     * @param RequestHandler $handler
     *
     * @return Response
     */
    public function process(Request $request, RequestHandler $handler)
    {
        $response = $handler->handle($request);
        return $response;
    }
}