Skip to content

Latest commit

 

History

History
114 lines (81 loc) · 3.67 KB

advanced-usage.rst

File metadata and controls

114 lines (81 loc) · 3.67 KB

Avanced Usage

Context

Each middleware is invoked with a Mw\Context instance. This is responsible for holding additional data to be used internally within the mw system and to provide additional features/usage for users. The context is available via the Mw\Link object of the middleware.

<?php

use Krak\Mw;

$handle = mw\compose([
    function($v, Mw\Link $next) {
        $ctx = $next->getContext();
        return 1;
    }
], new Krak\Mw\Context\StdContext());

You can configure or pass in any context as long as it implements the Mw\Context interface. Currently, the context provides an invoker via the getInvoke method. This allows custom invocation of the middleware as shown in the cookbook.

Custom Invocation

You can provide custom invocation of the middleware via the context. An invoker is any function that shares the signature of call_user_func. Its sole purpose is to invoke functions with their parameters. With custom invocation, you can do cool things like have middleware as pimple identifiers.

The final argument to each middleware is an instance of Mw\Link. The link is represents the link/chain between middlewares. Technically speaking, it's a singly-linked list of middleware that once executed will invoke the entire chain of middleware.

The link is responsible for building a set of middleware via the chain.

<?php

use Krak\Mw;

$link = new Mw\Link(function($i) {
    return $i * 2;
}, new Mw\Context\StdContext());
$link = $link->chain(function($i, $next) {
    return $next($i) + 1;
});
assert($link(2) == 5);

chain takes a middleware and produces a new link that is appened to the head of the linked list of mw links. As you can see, the middleware on the second link is executed first.

Meta Middleware

Custom Context and invocation is a very useful feature; however, it requires special consideration if you are creating your own Meta Middleware. Meta middleware are middleware that accept other middleware and inject middleware into the chain of middleware. :

mw\group
mw\lazy
mw\filter

These are all meta middleware. To allow all middleware to be properly linked and have access to the context, these meta middleware need to learn how to properly inject middleware into the mw link.

Here's an example:

<?php

use Krak\Mw;

// maybe middleware will only invoke the middleware if the parameter is < 10
function maybe($mw) {
    return function($i, $next) use ($mw) {
        if ($i < 10) {
            /** NOTE - this is the crucial part where we prepend the `$mw` onto the link. Now, when we execute `$next`,
                the `$mw` func will be first to be executed */
            $next = $next->chain($mw);
        }

        return $next($i);
    };
}

function loggingInvoke() {
    return function($func, ...$params) {
        echo "Invoking Middleware with Param: $params[0]\n";
        return call_user_func($func, ...$params);
    };
}

$handler = mw\compose([
    function() { return 1; },
    maybe(function($i, $next) {
        return $next($i) + 100;
    })
], new Mw\Context\StdContext(loggingInvoke()));

echo $handler(1) . PHP_EOL;
echo $handler(10) . PHP_EOL;

/*
Outputs:

Invoking Middleware with Param: 1
Invoking Middleware with Param: 1
Invoking Middleware with Param: 1
101
Invoking Middleware with Param: 10
Invoking Middleware with Param: 10
1
*/