Slim4 action handler with thirds (arguments) parameter not working

When I have an action class with __invoke method like this:

  public function __invoke( ServerRequestInterface $request,ResponseInterface $response,
    ): ResponseInterface
    {

all is working. But when I need to pass arrguments like in case of url /users/{id} I need to get id argument I make it like this:

  public function __invoke( ServerRequestInterface $request,ResponseInterface $response, array $arguments
    ): ResponseInterface
    {

and I’m getting error like

Invoker\Exception\NotEnoughParametersException. Code: 0. Message:Unable to invoke the callable because no value was given for parameter 3 ($arguments). File:vendor/php-di/invoker/src/Invoker.php. Line:78. 

My configurations looks like this:

        $definitions[Slim\CallableResolverInterface::class] = create(Slim\CallableResolver::class);
        $definitions[ResponseFactoryInterface::class] = create(ResponseFactory::class);
        $definitions[RouteCollector::class] = create(RouteCollector::class)->constructor(
            get(ResponseFactoryInterface::class),
            get(CallableResolverInterface::class)
        );

        $definitions[RouteCollectorInterface::class] = static function(Container $container) {
            $config = $container->get(Config::class);
            $collector = new RouteCollector(
                $container->get(ResponseFactoryInterface::class),
                $container->get(CallableResolverInterface::class)
            );

            if ((bool)$config->get('main.debug') === false && $config->has('main.routes_cache_dir')) {
                $collector->setCacheFile((string)$config->get('main.routes_cache_dir') .  '/route.cache');
            }

            return $collector;
        };

What I’m doing wrong?

I set up invocation strategy $definitions[InvocationStrategyInterface::class] = create(RequestHandler::class);

But I’m using DI\Bridge\Slim\Bridge to initialize slim app, and it has scuh a logic:

        $container = $container ?: new Container;

        $callableResolver = new InvokerCallableResolver($container);

        $container->set(CallableResolverInterface::class, new CallableResolver($callableResolver));
        $app = AppFactory::createFromContainer($container);

        $controllerInvoker = self::createControllerInvoker($container);
        $app->getRouteCollector()->setDefaultInvocationStrategy($controllerInvoker);

        return $app;

it’s overriding CallableResolverInterface::class definitions. . Also it’s using controller invoker, so no matter what invoker I set up. Maybe that is the case??

But when I replacing it with a AppFactory::create(); I’m getting error like:

Message: Argument 1 passed to Users\App\Interfaces\MiddleWares\XMLHttpRequestMiddleware::__construct() must implement interface Psr\Http\Message\ResponseFactoryInterface, null given, called in vendor/slim/slim/Slim/CallableResolver.php on line 149

and same with code like this:

        AppFactory::setContainer($container);
        $app = AppFactory::create();

and even if I passing container instance AppFactory::create(null, $container); to it’s not solving the issue.

ResponseFactoryInterface is configured in DI:

$definitions[ResponseFactoryInterface::class] = create(ResponseFactory::class);

So to assume when I’m using DI\Bridge\Slim\Bridge to initialize app I can’t pass the third argument I’as it by default using controller invoker and you can’t easily replace it with RequestHandler invoker. When I’m using AppFactory it’s not working at seems like it’s not injecting DI as it can’t resolve dependencies

I did it. It still should be controller invoker, but for some reason, in the DI\Bridge\Slim\Bridge it’s probably using wrong invocation strategy, so what I did is:

  1. I configure invocation strategy:

     $definitions[InvocationStrategyInterface::class] = create(ControllerInvoker::class)->constructor(
         new Invoker(new AssociativeArrayResolver())
     );
    
    1. I replace DI\Bridge\Slim\Bridge with own implementation
    public static function create(ContainerInterface $container = null): App
    {
    $container = $container ?: new Container;
    $callableResolver = new InvokerCallableResolver($container);
    $container->set(CallableResolverInterface::class, new CallableResolver($callableResolver));
    $app = AppFactory::createFromContainer($container);
    $app->getRouteCollector()->setDefaultInvocationStrategy($container->get(InvocationStrategyInterface::class));
    return $app;
    }
    

it’s doing almost the same as DI\Bridge\Slim\Bridge but it’s using invocation strategy I define, but DI\Bridge\Slim\Bridge override it with own