The PHP-DI edition
April 23, 2018 ยท View on GitHub
As explained in the dependency injection documentation, Silly can work with any dependency injection container.
However in order to provide an easy way to get started we provide a "PHP-DI edition" that is already configured with the PHP-DI container.
Installation
$ composer require mnapoli/silly-php-di
Usage
Simply use the alternative Application class offered by the PHP-DI bridge:
// Replace this
$app = new Silly\Application();
// with this:
$app = new Silly\Edition\PhpDi\Application();
Thanks to PHP-DI's autowiring capabilities you can define your commands in classes:
use Symfony\Component\Console\Output\OutputInterface;
class MyCommand
{
public function __invoke($name, OutputInterface $output)
{
if ($name) {
$text = 'Hello, '.$name;
} else {
$text = 'Hello';
}
$output->writeln($text);
}
}
$app = new Silly\Edition\PhpDi\Application();
$app->command('greet [name]', 'MyCommand');
$app->run();
PHP-DI will automatically create a new instance of MyCommand when the greet command is called.
Configuration
You can configure PHP-DI by overridding the createContainer() method in your Application class:
class MyApplication extends Silly\Edition\PhpDi\Application
{
protected function createContainer()
{
$builder = ContainerBuilder::buildDevContainer();
$builder->addDefinitions([
// add your PHP-DI config here
]);
return $builder->build(); // return the customized container
}
}
// In your main file you can now use your custom application class:
$app = new MyApplication();
If you do not want to go through the trouble of creating a new class, you can use PHP 7's anonymous classes:
$app = new class() extends Silly\Edition\PhpDi\Application
{
protected function createContainer()
{
$builder = ContainerBuilder::buildDevContainer();
$builder->addDefinitions([
// add your PHP-DI config here
]);
return $builder->build(); // return the customized container
}
};
Dependency injection in parameters
You can also use dependency injection in parameters:
use Psr\Logger\LoggerInterface;
// ...
$container = $app->getContainer();
$container->set('dbHost', 'localhost');
// Monolog's configuration is voluntarily skipped
$container->set(LoggerInterface::class, DI\object('Monolog\Logger'));
$app->command('greet [name]', function ($name, $dbHost, LoggerInterface $logger) {
// ...
});
$app->run();
Dependency injection in parameters follows the precedence rules explained in the dependency injection documentation:
- command parameters are matched in priority using the parameter names (
$name) - then container entries are matched using the callable type-hint (
Psr\Logger\LoggerInterface) - finally container entries are matched using the parameter names (
$dbHost)