0
votes

I decided to implement my own small framework to implement such stuff like dependency injection etc.

Now I'm stucking at my middleware implementation. I can add middleware to a route but I im wondering how slim loops through the attached middleware.

I'd like to do it the slim way, so in every middleware I can return a request or a response or the next middleware. But how do I have too iterate over my attached middleware.

Here is my stack I want to proceed

class MiddlewareStack
{

    private $stack;

    public function addMiddleware(Middleware $middleware)
    {
        $this->stack[] = $middleware;
    }

    public function processMiddleware(Request $request, Response $response)
    {
    }
}

and thats the middleware interface

public function __invoke(Request $request, Response $response, $next);

I want to

return $next($request,$response); 

in my middleware classes or just a response or a request.

Here's how to create middlware callable in slim.

http://www.slimframework.com/docs/concepts/middleware.html#invokable-class-middleware-example

1

1 Answers

3
votes

Slim 3 first adds itself to the stack which is the Slim\App#__invoke() which executes the route.

Then, when you add a middleware it does the following: (before this slim wrapps the callable (annonymous function/invokable class) inside a DeferredCallable which helps to execute both the function and class equally (See Slim\App#add()).

protected function addMiddleware(callable $callable) // $callable is a DeferredCallable
{
    $next = $this->stack->top(); // when it the first middleware this would be the route execution
    $this->stack[] = function (ServerRequestInterface $req, ResponseInterface $res) use ($callable, $next) {
        $result = call_user_func($callable, $req, $res, $next);
        return $result;
    };
}

(This is only the simple code, for full code see: Slim\MiddlewareAwareTrait#addMiddleware())

So the middleware which is on top of the stack executes the other middleware as well, because it is provided in the next method.

Then when you want to execute the middleware, get the middleware which is on top of the stack and execute it.

$start = $this->stack->top();
$resp = $start($req, $res);

// $resp is now the final response.

(see Slim\MiddlewareAwareTrait#callMiddlewareStack())