selective/container
Composer 安装命令:
composer require selective/container
包简介
A simple PSR-11 container implementation with autowiring.
关键字:
README 文档
README
Description
A PSR-11 container implementation with optional autowiring.
Requirements
- PHP 8.1 - 8.4
Installation
composer require selective/container
Usage
use Selective\Container\Container; $container = new Container(); // ... $myService = $container->get(MyService::class);
Enable Autowiring
The container is able to automatically create and inject dependencies for you. This is called "autowiring".
To enable autowiring you have to add the ConstructorResolver:
<?php use Selective\Container\Container; use Selective\Container\Resolver\ConstructorResolver; $container = new Container(); // Enable autowiring $container->addResolver(new ConstructorResolver($container)); //...
Defining DI Container Definitions
You can use a factories (closures) to define injections.
<?php use App\Service\MyService; use Selective\Container\Container; use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; $container = new Container(); // Add definition $container->factory(MyService::class, function (ContainerInterface $container) { return new MyService(); });
Defining Multiple DI Container Definitions
use Psr\Container\ContainerInterface; // ... $entries = [ MyService::class => function (ContainerInterface $container) { return new MyService(); }, PDO::class => function (ContainerInterface $container) { return new PDO('sqlite:example.db'); }, // and so on... ]; $container->factories($entries);
Service Providers
Service providers give the benefit of organising your container definitions along with an increase in performance for larger applications as definitions registered within a service provider are lazily registered at the point where a service is retrieved.
To build a service provider create a invokable class and return the definitions (factories) you would like to register.
<?php use App\Service\MyService; use Selective\Container\Container; use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; final class MyServiceFactoryProvider { /** * @return array<string, callable> */ public function __invoke(): array { return [ MyService::class => function (ContainerInterface $container) { return new MyService($container->get(LoggerInterface::class)); }, ]; } } $container->factories((new MyServiceFactoryProvider())());
Set definitions directly
In addition to defining entries in an array of factories / callbacks, you can also set the value directly as shown below:
$container->set(\App\Domain\MyService::class, new \App\Domain\MyService());
Fetching DI container entries
To fetch a value use the get method:
$pdo = $container->get(PDO::class);
Testing
- Make sure that your container will be recreated for each test. You may use the phpunit
setUp()method to initialize the container definitions. - You can use the
set()method to overwrite existing container entries.
Mocking
The set method can also be used to set mocked objects directly into the container.
This example requires phpunit:
<?php $class = \App\Domain\User\Repository\UserRepository::class; $mock = $this->getMockBuilder($class) ->disableOriginalConstructor() ->getMock(); $mock->method('methodToMock1')->willReturn('foo'); $mock->method('methodToMock2')->willReturn('bar'); $container->set($class, $mock);
Slim 4 integration
Example to boostrap a Slim 4 application using the container:
<?php use Selective\Container\Container; use Selective\Container\Resolver\ConstructorResolver; use Slim\App; use Slim\Factory\AppFactory; require_once __DIR__ . '/../vendor/autoload.php'; $container = new Container(); // Enable autowiring $container->addResolver(new ConstructorResolver($container)); // Load container definitions $container->factories(require __DIR__ . '/container.php'); // Create slim app instance AppFactory::setContainer($container); $app = AppFactory::create(); // Add routes, middleware etc... $app->run();
The container.php file must return an array of factories (closures):
<?php use Monolog\Logger; use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; return [ 'settings' => function () { return require __DIR__ . '/settings.php'; }, LoggerInterface::class => function (ContainerInterface $container) { $logger = new Logger('name'); // ... return $logger; }, // Add more definitions here... ]
PhpStorm Integration
If you use PhpStorm, then create a new file .phpstorm.meta.php
in your project root directory and copy/paste the following content:
<?php namespace PHPSTORM_META; override(\Psr\Container\ContainerInterface::get(0), map(['' => '@']));
Performance Comparison
selective/container is about:
- 11% faster then
php-di/php-di. - 5.4% faster then
league/container.
All tests where made with enabled autowiring.
Migrating from PHP-DI
This PSR-11 container implementation mimics the behavior of PHP-DI.
If you already use factories for your container definitions, the switch should be very simple.
Replace this:
<?php use DI\ContainerBuilder; // ... $containerBuilder = new ContainerBuilder(); $containerBuilder->addDefinitions(__DIR__ . '/container.php'); $container = $containerBuilder->build();
... with this:
<?php use Selective\Container\Container; use Selective\Container\Resolver\ConstructorResolver; // ... $container = new Container(); // Enable auto-wiring $container->addResolver(new ConstructorResolver($container)); // Add definitions $container->factories(require __DIR__ . '/container.php');
That's it.
Credits
- Dominik Zogg (chubbyphp)
Similar libraries
- https://github.com/chubbyphp/chubbyphp-container
- http://php-di.org/
- https://container.thephpleague.com/
License
The MIT License (MIT). Please see License File for more information.
selective/container 适用场景与选型建议
selective/container 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 23.51k 次下载、GitHub Stars 达 12, 最近一次更新时间为 2020 年 05 月 03 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「container」 「PSR-11」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 selective/container 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 selective/container 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 selective/container 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Facilitates the routine step of bootstrapping PHP applications.
A fast and intuitive dependency injection container.
PSR-11 Aura.DI container configurator for Laminas and Mezzio applications. Drop-in replacement for the archived laminas/laminas-auradi-config with PHP 8.4 and 8.5 support.
Symfony compiler pass that allows to use service providers as defined in container-interop/service-provider
Dependency injection container for the Monolith framework.
The PSR-11 container bridges
统计信息
- 总下载量: 23.51k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 13
- 点击次数: 13
- 依赖项目数: 4
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2020-05-03