Slim Framework 4 and Symfony Dependency Injection Component
Slim Framework 4 supports dependency injection containers that implement PSR-11 like Symfony DI or PHP-DI so you can choose which one to use.
In all official examples, the PHP-DI is favored against Symfony Dependency Injection Container.
PHP-DI is very nice, easy to use and “for humans” as they say. But in situations when you have multiple dependencies to be configured, the PHP-DI configuration file will become messy and not so “for humans”.
Experienced developers that have multiple frameworks working background will prefer loading config and wiring files from YAML files.
I had created a GitHub repository where I am demonstrating how easy is to use Symfony Dependency Injection Container with Slim Framework v4.
Symfony Dependency Injection Container
Symfony Dependency Injection is based on Symfony Service Container and all dependencies are configured in YAML files.
I chose to use the Symfony DOTENV package too because it is easier to change the configuration based on the environment.
/** composer.json */ "require": { "slim/slim": "^4.1", ... "symfony/config": "^5.0", "symfony/dependency-injection": "^5.0", "symfony/dotenv": "^5.0", "symfony/yaml": "^5.0" },
Swap the PHP-DI with the Symfony DI in the Slim Application
First, init the DotEnv and add the .env.dist file.
/** public/index.php */ $dotenv = new Dotenv(); $dotenv->loadEnv(__DIR__ . '/../.env');
/** .env.dist */ APP_ENV=dev APP_DEBUG=true LOGGER_NAME=slim-app LOGGER_PATH=/var/www/logs/app.log LOGGER_LEVEL=DEBUG
Then, move the PHP-DI from index.php file to a separate file:
/** public/index.php */ //$container = require __DIR__ . '/../app/did-container.php'; $container = require __DIR__ . '/../app/symfony-container.php';
Next, create the app/symfony-container.php file. The Symfony ConfigCache will load the already compiled container if the APP_DEBUG environment variable is set to FALSE.
/** app/symfony-container.php */ use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\DependencyInjection\Dumper\PhpDumper; use Symfony\Component\Config\ConfigCache; $file = __DIR__ . '/../var/cache/symfony-container.php'; $containerConfigCache = new ConfigCache($file, $_ENV['APP_DEBUG']); if (!$containerConfigCache->isFresh()) { $containerBuilder = new ContainerBuilder(); $fileLoader = new YamlFileLoader($containerBuilder, new FileLocator()); $fileLoader->load(__DIR__ . '/settings.yaml'); $fileLoader->load(__DIR__ . '/services.yaml'); $containerBuilder->compile(); $dumper = new PhpDumper($containerBuilder); $containerConfigCache->write( $dumper->dump(), $containerBuilder->getResources() ); } require_once $file; return new ProjectServiceContainer();
Create the setings.yaml and services.yaml files.
/** app/settings.yaml */ parameters: app.env: '%env(string:APP_ENV)%' app.debug: '%env(bool:APP_DEBUG)%' logger.name: '%env(string:LOGGER_NAME)%' logger.path: '%env(string:LOGGER_PATH)%' logger.level: '%env(string:LOGGER_LEVEL)%'
/** app/services.yaml */ parameters: services: _defaults: autowire: true autoconfigure: true public: false App\: resource: '../src/*' Monolog\Processor\UidProcessor: class: \Monolog\Processor\UidProcessor public: true log_handler: class: \Monolog\Handler\StreamHandler public: true arguments: - '%logger.path%' - '%logger.level%' logger: class: \Monolog\Logger public: true arguments: ['%logger.name%'] calls: - [pushHandler, ['@log_handler']] - [pushProcessor, ['@Monolog\Processor\UidProcessor']] App\Domain\User\UserRepository: class: \App\Infrastructure\Persistence\User\InMemoryUserRepository public: true App\Application\Actions\User\ListUsersAction: class: \App\Application\Actions\User\ListUsersAction public: true arguments: - '@logger' - '@App\Domain\User\UserRepository' App\Application\Actions\User\ViewUserAction: class: \App\Application\Actions\User\ViewUserAction public: true arguments: - '@logger' - '@App\Domain\User\UserRepository'
That’s it!
Test the following routes: home, users list, user view.
You can see all the modifications in this compared view:
https://github.com/slimphp/Slim-Skeleton/compare/master…floringavrila:master