squidit /container-mason
PSR-11 兼容的接口,用于统一创建新的容器实例和对象
v2.0.2
2024-07-08 17:05 UTC
Requires
- php: ^8.3
- psr/container: ^2.0
- psr/container-implementation: ^1.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.50
- league/container: ^4.2
- php-di/php-di: ^7.0
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^11.0
- squidit/php-coding-standards: ^1.0 || ^2.0
README
PSR-11 兼容的接口,用于统一创建新的容器实例和对象
为什么 / 用例
目前,有许多不同的 PSR-11 容器实现可用。不幸的是,它们并不总是以相同的方式工作。
根据容器实现或配置,从容器中获取条目可能会导致请求对象的不同实例。
<?php $serviceClass1 = $container->get(Service::class); $serviceClass2 = $container->get(Service::class); if ($serviceClass1 === $serviceClass2) { echo 'We got the same instance'; } else { echo 'We got 2 different instances'; }
强制新的对象实例也不是由 PSR-11 标准化的。根据容器实现,这可能是一个浅拷贝的新对象实例,或者是一个包含所有新实例化依赖项的完整新实例。
<?php $serviceClass1 = $container->make(Service::class); $serviceClass2 = $container->build(Service::class); $serviceClass3 = $container->getNew(Service::class);
协程
在实现和使用协程时,精确控制从容器中获取对象非常重要。或者提供一个带有自己的隔离容器的协程(取决于实现)。
这就是我创建这个接口的原因。
目标 - 实现接口
在实现此接口时,请确保遵循以下规则
- get() 方法 - 一定要返回相同的实例
- getNew() 方法 - 一定要返回一个具有新鲜依赖项的新实例(无共享)
- getNewMulti() 方法 - 一定要像 getNew() 一样工作,但总是返回一个数组,其中包含作为值的新实例,以及请求的 id 作为数组键
- getNewContainer() 方法 - 一定要返回一个新的容器实例
安装
您可以使用 composer 安装此包
composer require squidit/container-mason
此包不需要特定的 DI 容器,您需要实现提供的接口并包含您自己的 DI 容器。
示例容器:PHP-DI
链接/文档: PHP-DI 7。
composer require php-di/php-di
其他一些 PSR-11 容器
示例容器:非凡联盟 - 容器
链接/文档: 容器 The PHP League。
composer require league/container
接口
<?php declare(strict_types=1); namespace SquidIT\Container\Mason; use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; use Psr\Container\NotFoundExceptionInterface; interface ContainerMasonInterface extends ContainerInterface { /** * Find an entry of the container by its identifier and returns it. * The returned entry will always be the same object instance/value * * @param string $id Identifier of the entry to look for. * * @throws ContainerExceptionInterface Error while retrieving the entry. * @throws NotFoundExceptionInterface No entry was found for **this** identifier. * * @return mixed Entry. */ public function get(string $id): mixed; /** * Find entry inside the container using identifier and always return a new instance. * All dependencies of the requested identifier will be resolved again to create new instances of all dependencies * * @param string $id Identifier of the entry to look for. * * @throws ContainerExceptionInterface Error while retrieving the entry. * @throws NotFoundExceptionInterface No entry was found for **this** identifier. * * @return mixed Entry. */ public function getNew(string $id): mixed; /** * Find entries inside the container using identifiers and always return an array with new instances. * * @param string ...$ids Identifiers of the entries to look for. * * @throws ContainerExceptionInterface Error while retrieving the entry. * @throws NotFoundExceptionInterface No entry was found for **this** identifier. * * @return array<string, mixed> array key will be the id of the requested entry. */ public function getNewMulti(string ...$ids): array; /** * Always returns a new container instance */ public function getNewContainer(): ContainerInterface; }
示例
源代码目录包含两个文件夹
- League
- PhpDi
这两个文件夹都包含一个示例实现。