Loading repository data…
Loading repository data…
tomphp / repository
Configure your application and the Dependency Injection Container (DIC) via config arrays or config files.
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
This package enables you to configure your application and the Dependency Injection Container (DIC) via config arrays or files. Currently, supported containers are:
Installation can be done easily using composer:
$ composer require tomphp/container-configurator
<?php
use League\Container\Container; // or Pimple\Container
use TomPHP\ContainerConfigurator\Configurator;
$config = [
'db' => [
'name' => 'example_db',
'username' => 'dbuser',
'password' => 'dbpass',
],
'di' => [
'services' => [
'database_connection' => [
'class' => DatabaseConnection::class,
'arguments' => [
'config.db.name',
'config.db.username',
'config.db.password',
],
],
],
],
];
$container = new Container();
Configurator::apply()->configFromArray($config)->to($container);
$db = $container->get('database_connection');
Instead of providing the config as an array, you can also provide a list of
file pattern matches to the fromFiles function.
Configurator::apply()
->configFromFile('config_dir/config.global.php')
->configFromFiles('json_dir/*.json')
->configFromFiles('config_dir/*.local.php')
->to($container);
configFromFile(string $filename) reads config in from a single file.
configFromFiles(string $pattern) reads config from multiple files using
globbing patterns.
The reader matches files in the order they are specified. As files are read their config is merged in; overwriting any matching keys.
Currently .php and .json files are supported out of the box. PHP
config files must return a PHP array.
.yaml and .yml files can be read when the package symfony/yaml is
available. Run
composer require symfony/yaml
to install it.
All values in the config array are made accessible via the DIC with the keys
separated by a separator (default: .) and prefixed with constant string (default:
config).
$config = [
'db' => [
'name' => 'example_db',
'username' => 'dbuser',
'password' => 'dbpass',
],
];
$container = new Container();
Configurator::apply()->configFromArray($config)->to($container);
var_dump($container->get('config.db.name'));
/*
* OUTPUT:
* string(10) "example_db"
*/
Whole sub-arrays are also made available for cases where you want them instead of individual values.
$config = [
'db' => [
'name' => 'example_db',
'username' => 'dbuser',
'password' => 'dbpass',
],
];
$container = new Container();
Configurator::apply()->configFromArray($config)->to($container);
var_dump($container->get('config.db'));
/*
* OUTPUT:
* array(3) {
* ["name"]=>
* string(10) "example_db"
* ["username"]=>
* string(6) "dbuser"
* ["password"]=>
* string(6) "dbpass"
* }
*/
Another feature is the ability to add services to your container via the
config. By default, this is done by adding a services key under a di key in
the config in the following format:
$config = [
'di' => [
'services' => [
'logger' => [
'class' => Logger::class,
'singleton' => true,
'arguments' => [
StdoutLogger::class,
],
'methods' => [
'setLogLevel' => [ 'info' ],
],
],
StdoutLogger::class => [],
],
],
];
$container = new Container();
Configurator::apply()->configFromArray($config)->to($container);
$logger = $container->get('logger'));
You can create an alias to another service by using the service keyword
instead of class:
$config = [
'database' => [ /* ... */ ],
'di' => [
'services' => [
DatabaseConnection::class => [
'service' => MySQLDatabaseConnection::class,
],
MySQLDatabaseConnection::class => [
'arguments' => [
'config.database.host',
'config.database.username',
'config.database.password',
'config.database.dbname',
],
],
],
],
];
If you require some addition additional logic when creating a service, you can define a Service Factory. A service factory is simply an invokable class which can take a list of arguments and returns the service instance.
Services are added to the container by using the factory key instead of the
class key.
$appConfig = [
'db' => [
'host' => 'localhost',
'database' => 'example_db',
'username' => 'example_user',
'password' => 'example_password',
],
'di' => [
'services' => [
'database' => [
'factory' => MySQLPDOFactory::class,
'singleton' => true,
'arguments' => [
'config.db.host',
'config.db.database',
'config.db.username',
'config.db.password',
],
],
],
],
];
<?php
class MySQLPDOFactory
{
public function __invoke($host, $database, $username, $password)
{
$dsn = "mysql:host=$host;dbname=$database";
$pdo = new PDO($dsn, $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $pdo;
}
}
In the rare case that you want to inject the container in as a dependency to
one of your services, you can use Configurator::container() as the name
of the injected dependency. This will only work in PHP config files, it's not
available with YAML or JSON.
$config = [
'di' => [
'services' => [
ContainerAwareService::class => [
'arguments' => [Configurator::container()],
],
],
],
];
It is also possible to set up
Inflectors by adding an
inflectors key to the di section of the config.
$appConfig = [
'di' => [
'inflectors' => [
LoggerAwareInterface::class => [
'setLogger' => ['Some\Logger']
],
],
],
];
The behaviour of the Configurator can be adjusted by using the
withSetting(string $name, $value method:
Configurator::apply()
->configFromFiles('*.cfg.php'),
->withSetting(Configurator::SETTING_PREFIX, 'settings')
->withSetting(Configurator::SETTING_SEPARATOR, '/')
->to($container);
Available settings are:
| Name | Description | Default |
|---|---|---|
| SETTING_PREFIX | Sets prefix name for config value keys. | config |
| SETTING_SEPARATOR | Sets the separator for config key. | . |
| SETTING_SERVICES_KEY | Where the config for the services is. | di.services |
| SETTING_INFLECTORS_KEY | Where the config for the inflectors is. | di.inflectors |
| SETTING_DEFAULT_SINGLETON_SERVICES | Sets whether services are singleton by default. | false |
You can create your own custom file reader by implementing the
TomPHP\ContainerConfigurator\FileReader\FileReader interface. Once you have
created it, you can use the
withFileReader(string $extension, string $readerClassName) method to enable
the it.
IMPORTANT: withFileReader() must be called before calling
configFromFile() or configFromFiles()!
Configurator::apply()
->withFileReader('.xml', MyCustomXMLFileReader::class)
->configFromFile('config.xml'),
->to($container);
You can create your own container adapter so that you can configure other
containers. This is done by implementing the
TomPHP\ContainerConfigurator\FileReader\ContainerAdapter interface. Once you
have created your adapter, you can use the
withContainerAdapter(string $containerName, string $adapterName) method to
enable the it:
Configurator::apply()
->withContainerAdapter(MyContainer::class, MyContainerAdapter::class)
->configFromArray($appConfig),
->to($container);