中间件Middleware实现

数据结构

Closure Object
(
    [static] => Array
        (
            [stack] => Closure Object
                (
                    [static] => Array
                        (
                            [stack] => Closure Object
                                (
                                    [static] => Array
                                        (
                                            [stack] => Closure Object
                                                (
                                                    [parameter] => Array
                                                        (
                                                            [$param] => <required>
                                                        )

                                                )

                                            [middleware] => log_middleware
                                        )

                                    [parameter] => Array
                                        (
                                            [$param] => <required>
                                        )

                                )

                            [middleware] => filter_middleware
                        )

                    [parameter] => Array
                        (
                            [$param] => <required>
                        )

                )

            [middleware] => auth_middleware
        )

    [parameter] => Array
        (
            [$param] => <required>
        )

)

array_reduce实现Middleware

参考Laravel实现

<?php

function auth_middleware (Closure $callback, $param) {
    echo "auth middleware start, param: {$param}\n";
    $response = $callback($param);
    echo "auth middleware finish\n";
    return $response;
}

function filter_middleware (Closure $callback, $param) {
    echo "filter middleware start, param: {$param}\n";
    $response = $callback($param);
    echo "filter middleware finish\n";
    return $response;
}

function log_middleware (Closure $callback, $param) {
    echo "log middleware start, param: {$param}\n";
    $response = $callback($param);
    echo "log middleware finish\n";
    return $response;
}

$middleware = ['auth_middleware', 'filter_middleware', 'log_middleware'];

$run = array_reduce(array_reverse($middleware), function ($stack, $middleware) {
    return function ($param) use ($stack, $middleware) {
        return $middleware($stack, $param);
    };
}, function ($param) {
    echo "hello controller, param: {$param} \n";
});

call_user_func($run, 'stu_middleware');

// 输出
// auth middleware start, param: stu_middleware
// filter middleware start, param: stu_middleware
// log middleware start, param: stu_middleware
// hello controller, param: stu_middleware
// log middleware finish
// filter middleware finish
// auth middleware finish

closure实现Middleware

参考GuzzleHttp实现

<?php

$application = function($param) {
    echo "hello controller, param: {$param} \n";
};

$authMiddleware = function($handler) {
    return function($param) use ($handler) {
        echo "auth middleware start, param: {$param} \n";
        $response = $handler($param);
        echo "auth middleware finish \n";
        return $response;
    };
};

$filterMiddleware = function($handler) {
    return function($param) use ($handler) {
        echo "filter middleware start, param: {$param} \n";
        $response = $handler($param);
        echo "filter middleware finish \n";
        return $response;
    };
};

$logMiddleware = function($handler) {
    return function($param) use ($handler) {
        echo "log middleware start, param: {$param} \n";
        $response = $handler($param);
        echo "log middleware finish \n";
        return $response;
    };
};

function invoke($handler, $stack)
{
    foreach (array_reverse($stack) as $middleware) {
        $handler = $middleware($handler);
    }
    return $handler;
}

$stack = [
    'auth' => $authMiddleware,
    'filter' => $filterMiddleware,
    'log' => $logMiddleware
];

$run = invoke($application, $stack);

call_user_func($run, 'stu_middleware');

// 输出
// auth middleware start, param: stu_middleware
// filter middleware start, param: stu_middleware
// log middleware start, param: stu_middleware
// hello controller, param: stu_middleware
// log middleware finish
// filter middleware finish
// auth middleware finish