pyther/ioc
Composer 安装命令:
composer require pyther/ioc
包简介
Inversion of Control Container
README 文档
README
A simple lightweight PHP Inversion of Control (IoC) container with the following features:
- allow the creation of multiple or single(ton) instances
- goes hand in hand with Constructor Dependency Injection
- can bind to classes, methods, functions and instances
- trigger autoloader only during resolve phase (lazy loading)
- resolve nested dependencies, based on constructor DI
- can bind with optional arguments
- allow per instance arguments for non singletons during resolve phase
- detect cyclic dependencies on first use
- take default constructor arguments into account
- support for multiple, independent containers
- no external dependencies
- easy to use
Requirements
- php 8.1 or higher
Quickstart
Install the Composer Package
composer require pyther/ioc
Inversion of Control is a two way process. First you have to bind or register implementations of interfaces or classes to the container and then resolve (one or multile times) the creation of instances. And here is a fictional example:
use Pyther\Ioc\Ioc; // Let's bind an implementation of “MariaDatabase” as a singleton to an interface. // This ist afast process and will NOT trigger the autoloader. Ioc::bindSingleton(IDatabase::class, MariaDatabase::class); // later anywhere in your code, resolve to an instance of a MariaDatabase class $db = Ioc::get(IDatabase::class);
Why using an Ioc container
An IoC Container simplifies the creation of instances. It resolves object dependencies and is optimized to create instances on first use (lazy loading). It also makes it possible to replace classes with other (mock) implementations by changing one line of code. And it works perfectly with constructor dependency injections, forcing you to write cleaner code. It can also replace "global" collection classes.
In short, you define how instances are to be created, not when.
Binding
There are two general ways to bind implementations to the container.
The full syntax is:
bind[Singleton|Multiple](string name, string|callable|null implementation, array arguments = []) -> Ioc
The name is a unique name used later by the get method. The implementation must be a string (class name), any callable construction method, and existing object or null. arguments is an optional array of constructor arguments, indexed by argument name. These methods will return the Ioc container itself (usefull for chaining).
BindSingleton
Ioc::bindSingleton(ShoppingCart::class, ShoppingCart::class);
If you bind using bindSingleton the instance will be created on first use of Ioc::get(ShoppingCart::class).
All subsequent calls to the get method will always return the same instance.
BindMultiple
Ioc::bindMultiple(Product::class, Product::class);
This way any call of Ioc::get(Product::class) will return a new instance of the Product class.
Dependency Injection
A "Inversion of Control" container goes hand in hand with Constructor Dependency Injection.
Let's look at an example. Imagine we have a shopping cart that depends of the current logged in customer:
class ShoppingCart { function __construct(Customer $customer) { ... } }
If we bind the ShoppingCart and Customer class to the IoC container
// hint: the order of binding doesn't matter. Ioc::bindSingleton(ShippingCart::class, ShoppingCart::class); Ioc::bindSingleton(Customer::class, Customer::class);
and we resolve the ShoppingCart class using
$cart = Ioc::get(ShoppingCart::class);
the container want to create a new shopping cart and see it requires a customer class.
For this reason, a Customer instance is first created (if not already done) and passed as a parameter to the constructor of the ShoppingCart.
This nesting is recursive and takes “singletons” and “multiple” instances into account.
Of course, multiple constructor arguments are supported and cyclic dependencies are recognized when resolving via the get method and fires a Pyther\Ioc\Exceptions\ResolveException exception.
More control
This library gives you a lot control how objects will be instanced.
More binding control
For example you can add your own constructor arguments:
class Configurations { function __construct(?string $path = null) { ... } } ... Ioc::bindSingleton(Configurations::class, Configurations::class, ["path" => "./config.json"]);
As you can see, the default values for constructors are taken into account (if no arguments are found).
Another way is to create an anonymous construct function:
Ioc::bindSingleton(Configurations::class, function() { return new Configurations("./config.json); });
This function is only executed later when the object is first instantiated.
This way you can also have function arguments:
Ioc::bindSingleton(Configurations::class, function(string $path) { return new Configurations($path); }, ['path' => "./config.json"]);
This construct function can be also be a static method of another object:
$this->bindSingleton(IInterface::class, [AnyClass::class, "createObject"]); // or $this->bindSingleton(IInterface::class, "My\Namespace\AnyClass::createObject"); or with arguments $this->bindSingleton(IInterface::class, [AnyClass::class, "createObject"], [ "text" => "abc", "number"=> 123 ]); // or $this->bindSingleton(IInterface::class, "My\Namespace\AnyClass::createObject", [ "text" => "abc", "number"=> 123 ]);
Or as a method of an already instanced object:
$this->bindSingleton(IInterface::class, [$obj, "createObject"]); // or with arguments $this->bindSingleton(IInterface::class, [$obj, "createObject"], [ "text" => "abc", "number"=> 123 ]);
Binding to zero is also legitimate:
Ioc::bindSingleton(Configurations::class, null);
In this case, an exception is not thrown when resolving, but is resolved to zero.
And finally you can also bind an already existing objects:
$configs = new Configurations("./config.json"); ... Ioc::bindSingleton(Configurations::class, $configs);
Although this is possible, it should be avoided. On the one hand, the creation of the instances should be left to the container, on the other hand this triggers the autoloader and executes code that may never be needed.
More resolve control
For non singleton instances you can specifiy constructor arguments during the resolve phase:
class Product
{
public function __construct(string $sku) {
...
}
}
...
Ioc::bindMultiple(Product::class, Product::class);
...
Ioc::get(Product::class, ["sku" => "Product 001"];
...
Ioc::get(Product::class, ["sku" => "Product 002"];
Check if binding exists
To check if a binding exists, you can use the has method:
$exists = Ioc::has(Configurations::class);
Multiple Containers
If you have the rare case where you need more than one container, here we are.
The static methods of Ioc::bindSingleton(...), Ioc::bindMultiple(...) and Ioc::get(...) are suggar forms of
IoC::$default->addMultiple(...) IoC::$default->addSingleton(...) IoC::$default->resolve(...)
where Ioc::$default is the default container. This way you can have separated multiple containers:
$containerA = new Ioc(); $containerB = new Ioc(); $containerA->addSingleton(...); $containerB->addMutliple(...); $containerA->get(...);
I'm sure you get it :)
pyther/ioc 适用场景与选型建议
pyther/ioc 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 43 次下载、GitHub Stars 达 0, 最近一次更新时间为 2024 年 07 月 25 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「inversion of control」 「ioc」 「singleton」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 pyther/ioc 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 pyther/ioc 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 pyther/ioc 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Minimalist Dependency Injection Container.
Dependency injection (IoC) container for PHP projects
Provide a way to secure accesses to all routes of an symfony application.
Common IoC Api Interface
Molajo Inversion of Control package offers a full-featured, simple-to-use dependency injection and object construction solution for PHP applications.
Yii2 prettyPhoto image galary widget uses Lightbox view control jquery.prettyphoto.js
统计信息
- 总下载量: 43
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 20
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2024-07-25