定制 tomphp/container-configurator 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

tomphp/container-configurator

Composer 安装命令:

composer require tomphp/container-configurator

包简介

Configure your application and the Dependency Injection Container (DIC) via config arrays or config files.

README 文档

README

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

This package enables you to configure your application and the Dependency Injection Container (DIC) via config arrays or files. Currently, supported containers are:

Installation

Installation can be done easily using composer:

$ composer require tomphp/container-configurator

Example Usage

<?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');

Reading Files From Disk

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.

Merging

The reader matches files in the order they are specified. As files are read their config is merged in; overwriting any matching keys.

Supported Formats

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.

Application Configuration

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).

Example

$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"
 */

Accessing A Whole Sub-Array

Whole sub-arrays are also made available for cases where you want them instead of individual values.

Example

$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"
 * }
 */

Configuring Services

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'));

Service Aliases

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',
                ],
            ],
        ],
    ],
];

Service Factories

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.

Example Config

$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',
                ],
            ],
        ],
    ],
];

Example Service Factory

<?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;
    }
}

Injecting The Container

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()],
            ],
        ],
    ],
];

Configuring Inflectors

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']
            ],
        ],
    ],
];

Extra Settings

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

Advanced Customisation

Adding A Custom File Reader

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);

Adding A Custom Container Adapter

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);

tomphp/container-configurator 适用场景与选型建议

tomphp/container-configurator 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 40.43k 次下载、GitHub Stars 达 20, 最近一次更新时间为 2016 年 09 月 13 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「dependency injection」 「container」 「di」 「league」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 tomphp/container-configurator 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 tomphp/container-configurator 我们能提供哪些服务?
定制开发 / 二次开发

基于 tomphp/container-configurator 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 40.43k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 20
  • 点击次数: 18
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 20
  • Watchers: 3
  • Forks: 4
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2016-09-13