src/HandlerContainer.php
public function process(Request $request) : Response
    {
        $router = $request->attributes->get('router');
        
        $next = next($this->middlewareStack);
        if ($next instanceof Middleware) {
            $router->log("Router: Calling Middleware: %s", get_class($next));
            $response = $next->process($request, $this);
            $router->log("Router: Leaving Middleware: %s", get_class($next));
            return $response;
        } elseif (is_string($next)) {
            $router->log("Router: Calling Middleware: %s", $next);
            $response = $router->getMiddleware($next)->process($request, $this);
            $router->log("Router: Leaving Middleware: %s", $next);
            return $response;
        } else {
            $params = $request->attributes->get('controller');

            // Call controller with request and args
            $router->log("Router: Calling Controller: %s@%s", $params->className, $params->method);
            $return = (new $params->className($params->container))->{$params->method}($request, ...array_values($params->args));
            $router->log("Router: Controller Left");
            
            // Instantly return Response objects
            if ($return instanceof Response) {
                return $return;
            }
            
            // If not a string (or something easily castable to a string) assume Json -> JsonResponse
            if (is_array($return) or is_object($return)) {
                return new JsonResponse(
                    $return,
                    Response::HTTP_OK,
                    array('content-type' => 'application/json')
                );
            }
            
            // Strings, and other primitives.
            return new Response(
                $return,
                Response::HTTP_OK,
                array('content-type' => 'text/html')
            );
        }
    }
public function process(Request $request) : Response
    {
        $router = $request->attributes->get('router');
        
        $next = next($this->middlewareStack);
        if ($next instanceof Middleware) {
            $router->log("Router: Calling Middleware: %s", get_class($next));
            $response = $next->process($request, $this);
            $router->log("Router: Leaving Middleware: %s", get_class($next));
            return $response;
        } elseif (is_string($next)) {
            $router->log("Router: Calling Middleware: %s", $next);
            $response = $router->getMiddleware($next)->process($request, $this);
            $router->log("Router: Leaving Middleware: %s", $next);
            return $response;
        } else {
            $params = $request->attributes->get('controller');

            // Call controller with request and args
            $router->log("Router: Calling Controller: %s@%s", $params->className, $params->method);
            $return = (new $params->className($params->container))->{$params->method}($request, ...array_values($params->args));
            $router->log("Router: Controller Left");
            
            // Instantly return Response objects
            if ($return instanceof Response) {
                return $return;
            }
            
            // If not a string (or something easily castable to a string) assume Json -> JsonResponse
            if (is_array($return) or is_object($return)) {
                return new JsonResponse(
                    $return,
                    Response::HTTP_OK,
                    array('content-type' => 'application/json')
                );
            }
            
            // Strings, and other primitives.
            return new Response(
                $return,
                Response::HTTP_OK,
                array('content-type' => 'text/html')
            );
        }
    }
public function process ( Request $ request ) : Response { $ router = $ request -> attributes -> get ( 'router' ) ; $ next = next ( $ this -> middlewareStack ) ; if ( $ next instanceof Middleware ) { $ router -> log ( "Router: Calling Middleware: %s" , get_class ( $ next ) ) ; $ response = $ next -> process ( $ request , $ this ) ; $ router -> log ( "Router: Leaving Middleware: %s" , get_class ( $ next ) ) ; return $ response ; } elseif ( is_string ( $ next ) ) { $ router -> log ( "Router: Calling Middleware: %s" , $ next ) ; $ response = $ router -> getMiddleware ( $ next ) -> process ( $ request , $ this ) ; $ router -> log ( "Router: Leaving Middleware: %s" , $ next ) ; return $ response ; } else { $ params = $ request -> attributes -> get ( 'controller' ) ; // Call controller with request and args $ router -> log ( "Router: Calling Controller: %s@%s" , $ params -> className , $ params -> method ) ; $ return = ( new $ params -> className ( $ params -> container ) ) -> { $ params -> method } ( $ request , ... array_values ( $ params -> args ) ) ; $ router -> log ( "Router: Controller Left" ) ; // Instantly return Response objects if ( $ return instanceof Response ) { return $ return ; } // If not a string (or something easily castable to a string) assume Json -> JsonResponse if ( is_array ( $ return ) or is_object ( $ return ) ) { return new JsonResponse ( $ return , Response :: HTTP_OK , array ( 'content-type' => 'application/json' ) ) ; } // Strings, and other primitives. return new Response ( $ return , Response :: HTTP_OK , array ( 'content-type' => 'text/html' ) ) ; } }
Call middleware in order, and then call the specified Controller, using a modified PSR15 Middleware pattern

@param Request $request The request for the current route
@return Response
Call middleware in order and then call the specified Controller using a modified PSR15 Middleware pattern