tomphp/config-service-provider

此包已被弃用且不再维护。作者建议使用 tomphp/container-configurator 包代替。

通过配置数组或配置文件配置您的应用程序和依赖注入容器(DIC)。

v1.0.0 2016-10-31 18:34 UTC

This package is not auto-updated.

Last update: 2022-02-01 12:45:23 UTC


README

Build Status Scrutinizer Code Quality Latest Stable Version Total Downloads Latest Unstable Version License

此包允许您通过配置数组或文件配置您的应用程序和依赖注入容器(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) 使用通配符模式从多个文件中读取配置。

合并

读取器按照指定的顺序匹配文件。当读取文件时,其配置会被合并;覆盖任何匹配的键。

支持的格式

目前默认支持 .php.json 文件。PHP 配置文件 必须 返回一个 PHP 数组。

.yaml.yml 文件可以在有 symfony/yaml 包时读取。运行

composer require symfony/yaml

来安装它。

应用程序配置

配置数组中的所有值都可以通过 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);

可用设置有

名称 描述 默认值
SETTING_PREFIX 设置配置值键的前缀名称。 config
SETTING_SEPARATOR 设置配置键的分隔符。 .
SETTING_SERVICES_KEY 服务配置的位置。 di.services
SETTING_INFLECTORS_KEY 词法分析器配置的位置。 di.inflectors
SETTING_DEFAULT_SINGLETON_SERVICES 设置服务是否默认为单例。 false

高级定制

添加自定义文件读取器

您可以通过实现 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);