uniondrug/middleware

Uniondrug Middleware Component for uniondrug/framework

2.4.8 2018-09-14 04:03 UTC

This package is auto-updated.

Last update: 2024-03-09 16:30:37 UTC


README

基于Phalcon的uniondrug/framework项目中,增加中间件处理流程的支持。

感谢

https://github.com/limingxinleo/x-phalcon-middleware https://github.com/fastdlabs/middleware

安装

$ composer require uniondrug/middleware

使用

修改配置文件,引入中间件组件

app.php配置文件中增加中间件组件的注册

<?php
return [
    'default' => [
        ...
        'providers'           => [
            \Uniondrug\Middleware\MiddlewareServiceProvider::class,
        ],
        ...
    ],
];

添加middlewares.php配置文件,定义中间件

<?php
/**
 * middleware.php
 *
 */
return [
    'default' => [
        // 应用定义的中间件
        'middlewares' => [
            'test1' => \App\Middlewares\Test1Middleware::class,
            'test2' => \App\Middlewares\Test2Middleware::class,
            'test3' => \App\Middlewares\Test3Middleware::class,
            'test4' => \App\Middlewares\Test4Middleware::class,
            'test5' => \App\Middlewares\Test5Middleware::class,
        ],

        // 全局中间件,会应用在全部路由,优先级在应用定义之前
        'global'      => [
            'cors', 'cache', 'favicon', 'trace',
        ],

        // 全局中间件,会应用在全部路由,优先级在应用定义之后
        'globalAfter' => [
            'powered',
        ],

        // 以下是中间件用到的配置参数
        'cache'       => [
            'lifetime' => 60,
        ],
        'powered_by'  => 'Un',
    ],
];

开发中间件

创建中间件。中间件必须从Uniondrug\Middleware\Middleware继承。实现handle方法。该方法有两个参数:request是Phalcon的Phalcon\Http\Request对象,next是下一个中间件代理。 在处理过程中,可以直接返回一个Phalcon\Http\Response对象,终止后续的中间件,或者返回下一个中间件代理的处理结果(链式传递)。

<?php
/**
 * Test1Middleware.php
 *
 */

namespace App\Middlewares;

use Phalcon\Http\RequestInterface;
use Uniondrug\Middleware\DelegateInterface;
use Uniondrug\Middleware\Middleware;

class Test1Middleware extends Middleware
{
    public function handle(RequestInterface $request, DelegateInterface $next)
    {
        echo "Test1.0\n";
        $response = $next($request);
        echo "Test1.1\n";
        return $response;
    }
}

中间件开发好后,需要在middleware.php配置文件中注册一个别名,在使用过程中以别名调用。

使用中间件

中间件在控制器中使用。在控制器中有两种方法定义需要使用哪些中间件。

1、在beforeExecuteRoute()方法中配置。

通过middlewareManager组件的bind方法,指派对应的中间件。

其中第一个参数是控制器本身,

第二个参数是一组中间件别名,

可选的第三个参数可以指明中间件的绑定范围: only 指只有在列表中的 action 使用该组中间件 except 指除了列表中的 action 以外的所有方法使用该组中间件 如果only/except都不指定,那么整个控制器的方法都会使用改组中间件

2.通过注解的方法定义中间件

注解Middleware定义当前控制器或者方法使用的中间别名。可以定义多个。

<?php
/**
 * IndexController.php
 *
 */
namespace App\Controllers;

use Phalcon\Mvc\Controller;

/**
 * Class IndexController
 *
 * @package App\Controllers
 * @Middleware('test1')
 */
class IndexController extends Controller
{
    public function beforeExecuteRoute($dispatcher)
    {
        $this->middlewareManager->bind($this, ['test2']);
        $this->middlewareManager->bind($this, ['test3'], ['only' => ['indexAction']]);
    }

    /**
     * @Middleware('test4', 'test5')
     */
    public function indexAction()
    {
        //var_dump($this->middlewareManager);
        return $this->response->setJsonContent(['msg' => memory_get_usage()]);
    }

    public function showAction()
    {
        return $this->response->setJsonContent(['msg' => 'show']);
    }
}

中间件调用的顺序

  • -> 配置文件定义的global定义的中间件
  • -> bind()方法绑定到控制器上的中间件
  • -> 控制器的注解上定义的中间件
  • -> bind()方法绑定到的Action方法上的中间件
  • -> Action方法的注解定义的中间件
  • -> 配置文件定义的globalAfter定义的中间件

bind()方法定义超过一个中间件时,从后到先倒序执行。

比如上面例子里面的indexAction被调用时,中间件的执行顺序是:

前置调用

  • test2 -> test1 -> test3 -> test4 -> test5

后置调用

  • test5 -> test4 -> test3 -> test1 -> test2

前置调用 & 后置调用

NOTE:Phalcon的Request对象不同于Psr的HttpRequest对象,它只是PHP原生超全局变量$_GET/$_POST/$_SERVER/$_REQUEST的封装,所以如果想在Middleware中对请求对象进行 改写并且让他影响后续使用,那么直接操作超全局变量。

class Test1Middleware extends Middleware
{
    public function handle(RequestInterface $request, DelegateInterface $next)
    {
        echo "Test1.0\n"; // 在 $next($request) 之前的代码,将在请求被最终Controller::Action处理之前调用
        $_POST['added_var'] = 'new value'; // 改写请求参数,往Request中添加一个新的POST参数。
                                           // 这样下一个Middleware乃至Controller::Action中使用 `$request` 对象的 `getPost()` 方法就能获取到新的参数值了。
        $response = $next($request);
        echo "Test1.1\n"; // 在 $next($request) 之后的代码,将在请求被最终Controller::Action处理之后调用
        return $response;
    }
}

内置中间件

组件自带了几个实用的中间件,在middleware.php配置文件中增加配置即可使用。

  • cors 跨域资源共享
  • trace 跟踪服务
  • cache 缓存中间件,只对GET请求有效
  • powered 增加PoweredBy头
  • favicon 过滤favicon.ico请求