nbish11 / dice
一个轻量级的PHP依赖注入容器(DIC)。请注意:3.0及以上版本仅与PHP 7.0兼容。2.0分支与PHP 5.6兼容。
Requires
- php: >=7.0.0
Requires (Dev)
- phpunit/phpunit: ^6.5
This package is auto-updated.
Last update: 2024-09-10 04:50:33 UTC
README
Dice是一个专注于轻量级、快速以及尽可能少配置的PHP依赖注入容器。
项目目标
-
要轻量级,不是由数十个文件组成的庞大库(Dice是一个100行代码的单个类),同时支持更复杂容器提供的所有功能(及更多)
-
要“直接使用”。基本功能应该可以在零配置的情况下工作
-
在需要配置的地方,它应该是尽可能最小化和可重用的,并且易于使用。
-
速度!(请参阅性能部分)
安装
只需在您的项目中包含轻量级的Dice.php
,它就可以在不进行任何进一步配置的情况下使用
简单示例
<?php class A { public $b; public function __construct(B $b) { $this->b = $b; } } class B { } require_once 'Dice.php'; $dice = new \Dice\Dice; $a = $dice->create('A'); var_dump($a->b); //B object ?>
完整文档
请参阅Dice PHP依赖注入容器主页获取完整文档
PHP版本兼容性
Dice与PHP 7.0及更高版本兼容,存在支持PHP 5.6的Dice存档版本,但不再维护。
性能
Dice使用反射,这通常被错误地标记为“慢”。反射比加载和解析配置文件要快得多。这里有一系列基准测试在这里和在这里(要自行下载基准测试工具,请参阅此存储库)并且Dice在大多数情况下都比其他容器快。
在实际测试中(测试6),Dice与Pimple(需要编写大量配置代码)并驾齐驱,尽管Symfony\DependencyInjection在创建对象方面更快,但它有更大的开销,并且您需要在每个页面加载时创建超过500个对象,直到它比Dice快。Phalcon也是如此,加载Phalcon扩展的开销意味着除非您在每个HTTP请求中创建超过一千个对象,否则开销是不值得的。
致谢
最初由Tom Butler (@TomBZombie) 开发,感谢daniel-meister (@daniel-meister)、Garrett W. (@garrettw)、maxwilms (@maxwilms) 对错误修复、建议和改进。
更新
2018年11月15日 4.0版本发布 - 不向后兼容
Dice现在是不可变的,并且对其他不可变对象有更好的支持。
新功能
1. Dice是不可变的
这避免了Dice实例在应用程序中传递并重新配置的可变性问题。唯一的区别是addRules
和addRule
返回一个新的Dice实例,其中包含更新后的规则,而不是改变现有实例的状态。
// Pre-4.0 code: $dice->addRule('PDO', ['shared' => true]); $db = $dice->create('PDO'); // 4.0 code: $dice = $dice->addRule('PDO', ['shared' => true]); $db = $dice->create('PDO');
从实际的角度来看,在大多数情况下,只需在任何$dice->addRule()
调用前加上$dice =
即可,它将像以前一样工作。
2. 支持对象方法链
不可变对象的一些功能是它们提供对象链。
考虑以下对象
$httpRequest = new HTTPRequest(); $httpRequest = $httpRequest->url('http://example.org')->method('POST')->postdata('foo=bar');
在之前的版本中,Dice无法构建配置的对象。从4.0版本开始,Dice支持使用call
规则和Dice::CHAIN_CALL
常量进行方法链调用。
$dice = $dice->addRule('HTTPRequest', ['call' => [ ['url', ['http://example.org'], Dice::CHAIN_CALL], ['method', ['POST'], Dice::CHAIN_CALL ], ['postdata', ['foo=bar'], Dice::CHAIN_CALL] ] ] );
Dice会将链式调用的结果替换为HTTPRequest对象。这对于工厂类来说也非常有用。
$dice = $dice->addRule('MyDatabase', [ 'instanceOf' => 'DatabaseFactory', 'call' => [ ['get', ['Database'], Dice::CHAIN_CALL] ] ] ); $database = $dice->create('MyDatabase'); //Equivalent of: $factory = new DatabaseFactory(); $database = $factory->get('Database');
2018年6月3日 3.0版本发布 - 不兼容向下
新功能
1. 移除了JSON加载器,转而使用新的addRules
方法。
$dice->addRules([ '\PDO' => [ 'shared' => true ], 'Framework\Router' => [ 'constructParams' => ['Foo', 'Bar'] ] ]);
添加此功能的目的是使JSON加载器变得冗余。通过以下代码可以轻松地从JSON文件加载规则:
$dice->addRules(json_decode(file_get_contents('rules.json')));
2. 改进了对JSON文件的支持:常量和超全局变量
为了提高对外部JSON文件中定义的规则的支持,现在可以将常量和超全局变量传递给Dice创建的对象。
例如,将$_SERVER
超全局变量传递给路由器实例,并使用PDO的setAttribute
方法以及PDO::ATTR_ERRMODE
和PDO::ERRMODE_EXCEPTION
,可以在JSON文件中这样实现:
rules.json
{ "Router": { "constructParams": [ {"Dice::GLOBAL": "_SERVER"} ] }, "PDO": { "shared": true, "constructParams": [ "mysql:dbname=testdb;host=127.0.0.1", "dbuser", "dbpass" ], "call": [ [ "setAttribute", [ {"Dice::CONSTANT": "PDO::ATTR_ERRMODE"}, {"Dice::CONSTANT": "PDO::ERRMODE_EXCEPTION"} ] ] ] } }
$dice->addRules(json_decode(file_get_contents('rules.json')));
不兼容的变更
-
Dice 3.0需要PHP 7.0或更高版本,不再支持PHP 5.6。
-
Dice不再支持用
'instance'
键表示实例。例如
$dice->addRule('ClassName', [ 'constructParams' => ['instance' => '$NamedPDOInstance'] ]);
如问题#125所述,这使数组无法传递给构造函数,如果数组中有'instance'
键。相反,应使用新的\Dice\Dice::INSTANCE
常量。
$dice->addRule('ClassName', [ 'constructParams' => [\Dice\Dice::INSTANCE => '$NamedPDOInstance'] ]);
为了使常量更易于输入,可以使用use \Dice\Dice;
并引用Dice::INSTANCE
10/06/2016
** 不兼容的变更 **
根据问题110,现在使用instanceOf
命名的实例将继承它们所属类的规则。
$rule = []; $rule['shared'] = true; $dice->addRule('MyClass', $rule); $rule = []; $rule['instanceOf'] = 'MyClass'; $rule['constructParams'] = ['Foo', 'Bar']; $dice->addRule('$MyNamedInstance', $rule);
$dice->create('$MyNamedInstance')
现在将创建一个遵循应用于MyClass
和$MyNamedInstance
的规则的类,因此实例将是共享的。
以前只使用命名实例的规则。
要恢复旧的行为,请将命名实例上的inherit
设置为false
。
$rule = []; $rule['shared'] = true; $dice->addRule('MyClass', $rule); $rule = []; $rule['instanceOf'] = 'MyClass'; $rule['constructParams'] = ['Foo', 'Bar']; //Prevent the named instance inheriting rules from the class named in `instanceOf`: $rule['inherit'] = false; $dice->addRule('$MyNamedInstance', $rule);
29/10/2014
- 根据问题#15,Dice现在只有在闭包被\Dice\Instance包装时才会调用闭包。**请注意:这是不兼容的变更**。
以前,Dice会运行作为替换、constructParams以及调用方法时传递的闭包。
$rule->substitutions['A'] = function() { return new A; }; $rule->call[] = ['someMethod', function() { // '2' will be provided as the first argument when someMethod is called return 2; }]; $rule->constructParams[] = function() { //'abc' will be providedas the first constructor parameter return 'abc'; };
由于闭包始终被调用和执行,因此此行为已更改,这使得无法提供闭包作为构造参数或调用方法,因为闭包总是被调用和执行。
为了克服这个问题,Dice现在只有在闭包被\Dice\Instance包装时才会调用闭包。
$rule->substitutions['A'] = ['instance' => function() { return new A; }]; $rule->call[] = ['someMethod', ['instance' => function() { // '2' will be provided as the first argument when someMethod is called return 2; }]]); $rule->constructParams[] = ['instance' => function() { { //'abc' will be providedas the first constructor parameter return 'abc'; }]);
04/09/2014
- 推送PHP5.6分支。这稍微更高效地使用了PHP5.6的特性。对于PHP5.4-PHP5.5,请参阅相关分支。此版本将在PHP5.6更广泛地使用之前得到维护。
26/08/2014
- 添加PHP5.6分支。通过使用PHP5.6特性整理了代码。当PHP5.6发布时,这将转移到master分支。
28/06/2014
- 效率大大提高。Dice现在是PHP中最快的依赖注入容器!
06/06/2014
- 增加了对循环引用的支持( https://github.com/TomBZombie/Dice/issues/7)。请注意,这是糟糕的设计,但这个修复将阻止该设计创建的无穷循环。
27/03/2014
- 移除了assign()方法,因为使用$rule->shared可以获得相同的功能。
- 移除了$dice->create()中的$callback参数,因为这个功能的唯一实际用途可以通过$dice->shareInstances更好地实现。
- 整理了代码,移除了未使用或未记录的特性。Dice现在更轻量级且更快。
- 修复了一个bug,该bug在使用$rule->call时,每次调用方法都会使用构造函数中的替换规则
- 更新了Dice文档,以使用简写数组语法
01/03/2014
- 为Xml Loader和Loader Callback类添加了测试用例
- 添加了JSON loader + 测试用例
- 将所有测试用例添加到测试套件中
- 迁移到PHP5.4数组语法。PHP5.3兼容版本现在可在PHP5.3分支中找到。
- 修复了使用命名实例时,每次创建类都会触发自动加载器并使用无效类名的问题
28/02/2014
- 添加了基本命名空间支持。文档更新将随后进行。同时将XML loader移动到自己的文件中,如果你使用它,需要单独包含。
- 请注意:这些更改**不向后兼容**。但是,可以通过以下查找/替换操作轻松修复:
new Dice => new \Dice\Dice new DiceInstance => new \Dice\Instance new DiceRule => new \Dice\Rule