tomphp / container-configurator
通过配置数组或配置文件来配置您的应用程序和依赖注入容器(DIC)。
Requires
- php: ^5.6|^7.0
- beberlei/assert: ^2.6
- tomphp/exception-constructor-tools: ^1.0.0
Requires (Dev)
- friendsofphp/php-cs-fixer: 2.0.0-alpha
- league/container: ^2.0.2
- phpunit/phpunit: ^5.5.4
- pimple/pimple: ^3.0.0
- squizlabs/php_codesniffer: *
- symfony/yaml: ^3.1.4
Suggests
- league/container: Small but powerful dependency injection container http://container.thephpleague.com
- pimple/pimple: A small PHP 5.3 dependency injection container http://pimple.sensiolabs.org
- symfony/yaml: For reading configuration from YAML files
README
此包允许您通过配置数组或文件来配置您的应用程序和依赖注入容器(DIC)。目前支持的容器有
安装
可以使用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');
从磁盘读取文件
除了提供配置数组外,您还可以向fromFiles
函数提供一个文件模式匹配列表。
Configurator::apply() ->configFromFile('config_dir/config.global.php') ->configFromFiles('json_dir/*.json') ->configFromFiles('config_dir/*.local.php') ->to($container);
configFromFile(string $filename)
从单个文件中读取配置。
configFromFiles(string $pattern)
使用globbing模式从多个文件中读取配置。
合并
读取器按照指定的顺序匹配文件。读取文件时,它们的配置会被合并;覆盖任何匹配的键。
支持的格式
目前默认支持.php
和.json
文件。PHP配置文件必须返回一个PHP数组。
当有symfony/yaml
包时,可以读取.yaml
和.yml
文件。运行以下命令来安装它。
composer require symfony/yaml
to install it.
应用程序配置
配置数组中的所有值都可以通过DIC访问,键由分隔符(默认为.
)分隔,并以前置字符串(默认为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" */
访问整个子数组
当您需要整个子数组而不是单个值时,也会提供整个子数组。
示例
$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" * } */
配置服务
另一个功能是通过配置添加服务到您的容器。默认情况下,这是通过在配置中的di
键下添加一个services
键来完成的,格式如下
$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'));
服务别名
您可以通过使用service
关键字而不是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', ], ], ], ], ];
服务工厂
如果您在创建服务时需要一些额外的逻辑,您可以定义一个服务工厂。服务工厂是一个可调用的类,它可以接受一系列参数并返回服务实例。
通过使用factory
键而不是class
键来将服务添加到容器中。
示例配置
$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; } }
注入容器
在极少数情况下,如果您想将容器注入为某个服务的依赖项,可以使用Configurator::container()
作为注入依赖项的名称。这只能在PHP配置文件中工作,在YAML或JSON中不可用。
$config = [ 'di' => [ 'services' => [ ContainerAwareService::class => [ 'arguments' => [Configurator::container()], ], ], ], ];
配置词形转换器
您还可以通过向配置的di
部分添加一个inflectors
键来设置词形转换器。
$appConfig = [ 'di' => [ 'inflectors' => [ LoggerAwareInterface::class => [ 'setLogger' => ['Some\Logger'] ], ], ], ];
额外设置
可以通过使用withSetting(string $name, $value
方法来调整Configurator
的行为。
Configurator::apply() ->configFromFiles('*.cfg.php'), ->withSetting(Configurator::SETTING_PREFIX, 'settings') ->withSetting(Configurator::SETTING_SEPARATOR, '/') ->to($container);
可用的设置有
高级自定义
添加自定义文件读取器
您可以通过实现 TomPHP\ContainerConfigurator\FileReader\FileReader
接口来创建自己的自定义文件读取器。创建后,您可以使用 withFileReader(string $extension, string $readerClassName)
方法来启用它。
重要:withFileReader()
必须在调用 configFromFile()
或 configFromFiles()
之前调用!
Configurator::apply() ->withFileReader('.xml', MyCustomXMLFileReader::class) ->configFromFile('config.xml'), ->to($container);
添加自定义容器适配器
您可以创建自己的容器适配器,以便配置其他容器。这是通过实现 TomPHP\ContainerConfigurator\FileReader\ContainerAdapter
接口来完成的。创建适配器后,您可以使用 withContainerAdapter(string $containerName, string $adapterName)
方法来启用它
Configurator::apply() ->withContainerAdapter(MyContainer::class, MyContainerAdapter::class) ->configFromArray($appConfig), ->to($container);