Psr17Factory cannot be resolved

Hello, after adding the ValidationExceptionMiddleware to my application like described here I get the following error:
Message: Entry "Slim\Factory\Psr17\Psr17Factory" cannot be resolved: the class is not instantiable Full definition: Object ( class = #NOT INSTANTIABLE# Slim\Factory\Psr17\Psr17Factory lazy = false )

My whole setup is based on this manual: Slim 4 - Tutorial | Daniel Opitz - Blog
When I remove $app->add(ValidationExceptionMiddleware::class); to the middleware.php it works fine (without catching my validation errors correctly).

What am I doing wrong that the whole factory cannot be resolved?

Middleware.php:

<?php

use Selective\BasePath\BasePathDetector;
use Selective\BasePath\BasePathMiddleware;
use Selective\Validation\Middleware\ValidationExceptionMiddleware;
use Slim\App;
use Slim\Middleware\ContentLengthMiddleware;
use Slim\Middleware\ErrorMiddleware;

return function (App $app) {
    // Parse json, form data and xml
    $app->addBodyParsingMiddleware();

    $app->add(ValidationExceptionMiddleware::class);

    // Add the Slim built-in routing middleware
    $app->addRoutingMiddleware();

    // Catch exceptions and errors
    $app->add(ErrorMiddleware::class);

    // Calculate Content-Length header
    $app->add(new ContentLengthMiddleware());

    //Autodetect project directory name
    $basePath = (new BasePathDetector($_SERVER))->getBasePath();
    $basePathApi = $basePath . '/public';
    $app->setBasePath($basePathApi);
    /*$app->add(BasePathMiddleware::class);*/

    //Authentication
    $app->add(new Tuupola\Middleware\JwtAuthentication([
        "attribute" => "jwt",
        "ignore" => [$basePathApi."/login/", $basePathApi."/register", $basePathApi."/user", $basePathApi."/"],
        "secret" => "supersecretkeyyoushouldnotcommittogithub"
    ]));
};

And here is my container.php:

<?php

use Laminas\Config\Factory;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Selective\Validation\Encoder\JsonEncoder;
use Selective\Validation\Middleware\ValidationExceptionMiddleware;
use Selective\Validation\Transformer\ErrorDetailsResultTransformer;
use Slim\App;
use Slim\Factory\AppFactory;
use Slim\Factory\Psr17\Psr17Factory;
use Slim\Middleware\ErrorMiddleware;
use Selective\BasePath\BasePathMiddleware;

$configFiles = [];
if (file_exists('../config/variables/default.json')) $configFiles[] = '../config/variables/default.json';
if (file_exists('../config/variables/local.json')) $configFiles[] = '../config/variables/local.json';
$settings = Factory::fromFiles($configFiles);

if (array_key_exists('php', $settings)) {
// Should be set to 0 in production
    if (array_key_exists('error_reporting', $settings['php'])) {
     if (is_integer($settings['php']['error_reporting'])) error_reporting($settings['php']['error_reporting']);
     if (is_string($settings['php']['error_reporting'])) error_reporting(constant($settings['php']['error_reporting']));;
    }

// Should be set to '0' in production
    if (array_key_exists('ini', $settings['php'])) {
        foreach ($settings['php']['ini'] as $key => $value) {
            ini_set($key, $value);
        }
    }

// Timezone
    if (array_key_exists('date_default_timezone', $settings['php'])) date_default_timezone_set($settings['php']['date_default_timezone']);
}

return [
    'settings' => function () use ($settings) {
        return $settings;
    },

    ValidationExceptionMiddleware::class => function (ContainerInterface $container) {
        $factory = $container->get(ResponseFactoryInterface::class);

        return new ValidationExceptionMiddleware(
            $factory,
            new ErrorDetailsResultTransformer(),
            new JsonEncoder()
        );
    },

    App::class => function (ContainerInterface $container) {
        AppFactory::setContainer($container);

        return AppFactory::create();
    },

    ResponseFactoryInterface::class => function (ContainerInterface $container) {
        return $container->get(Psr17Factory::class);
    },

    ErrorMiddleware::class => function (ContainerInterface $container) {
        $app = $container->get(App::class);
        $settings = $container->get('settings')['slim']['error'];

        return new ErrorMiddleware(
            $app->getCallableResolver(),
            $app->getResponseFactory(),
            (bool)$settings['display_error_details'],
            (bool)$settings['log_errors'],
            (bool)$settings['log_error_details']
        );
    },

    BasePathMiddleware::class => function (ContainerInterface $container) {
        return new BasePathMiddleware($container->get(App::class));
    },

    PDO::class => function (ContainerInterface $container) {
        $settings = $container->get('settings')['db'];

        $host = $settings['host'];
        $dbname = $settings['database'];
        $username = $settings['user'];
        $password = $settings['password'];
        $charset = $settings['charset'];
        $flags = $settings['flags'];
        $dsn = "mysql:host=$host;dbname=$dbname;charset=$charset";

        return new PDO($dsn, $username, $password, $flags);
    },

];

Is it maybe the code reading the settings that I wrote in the container.php? This is the only variation from the above instructions.

Thank you!

Message: Entry “Slim\Factory\Psr17\Psr17Factory” cannot be resolved:

This error means that the DI container definition for Psr17Factory::class is missing.

In your specific case, it’s the Factory itself which is not correct.

Replace

use Slim\Factory\Psr17\Psr17Factory;

with this:

use Nyholm\Psr7\Factory\Psr17Factory;
1 Like

That worked. Thank you. without your help I could have searched for a long time…

1 Like