lkrms/dice

PHP 依赖注入容器的极简主义实现。由 level-2/dice 分支而来。

维护者

详细信息

github.com/lkrms/Dice

主页

源码

v4.1.10 2024-05-31 05:58 UTC

README

注意:这是 Tom Butler 的项目 Dice 的分支。它反映了使用它的 PHP 工具包 的需求和优先级,可能或可能不与您的需求一致。

Dice PHP 依赖注入容器

Dice 是一个针对 PHP 的极简依赖注入容器,注重轻量级、快速以及尽可能少的配置。

项目目标

  1. 要轻量级,不是一个包含数十个文件的庞大库(Dice 是一个类),同时支持比更复杂的容器所有(和更多)的功能。

  2. 要“直接工作”。基本功能应该无需配置即可使用。

  3. 当需要配置时,它应该尽可能最小化和可重用,并且易于使用。

  4. 速度!(请参阅性能部分

安装

使用 Composer 安装此分支的最新版本

composer require lkrms/dice

或者,将轻量级的 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 8+。

性能

Dice 使用反射,这通常被错误地标记为“慢”。反射比加载和解析配置文件要快得多。这里有一些基准测试这里(要自己下载基准测试工具,请参阅此存储库),Dice 在大多数情况下比其他容器更快。

在实际测试中(测试 6),Dice 与 Pimple(需要编写大量的配置代码)并驾齐驱,尽管 Symfony\DependencyInjection 在创建对象方面更快,但它有更大的开销,并且需要在每次页面加载时创建超过 500 个对象,直到它比 Dice 更快。Phalcon 的情况也是如此,加载 Phalcon 扩展的开销意味着除非您在每个 HTTP 请求中创建超过一千个对象,否则开销不值得。

鸣谢

最初由 Tom Butler (@TomBZombie) 开发,感谢 daniel-meister (@daniel-meister)、Garrett W. (@garrettw)、maxwilms (@maxwilms) 为错误修正、建议和改进所做的贡献。

此分支由 Luke Arms (@lkrms) 维护。

更新

2018 年 11 月 15 日 4.0 版本发布 - 不兼容回退

Dice 现在是不可变的,并且对其他不可变对象有更好的支持。

新功能

1. Dice 是不可变的

这避免了在应用程序中传递 Dice 实例并重新配置时围绕可变性的问题。唯一的区别是,addRulesaddRule 返回一个新的 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::ATTR_ERRMODEPDO::ERRMODE_EXCEPTION 调用 PDO 的 setAttribute 可以像这样在 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')));

不兼容的更改

  1. Dice 3.0 需要 PHP 7.0 或更高版本,不再支持 PHP 5.6。

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

2016年10月6日 - 不兼容的更改

根据 问题 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 的规则,因此实例将是共享的。

以前,仅使用命名实例的规则。

要恢复旧行为,请在命名实例上设置 inheritfalse

$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

27/03/2014

  • 移除了assign()方法,因为可以使用$rule->shared获得相同的功能。
  • 移除了在$dice->create()中的$callback参数,因为这个功能的唯一实际用途可以通过使用$rule->shareInstances更好地实现。
  • 整理了代码,移除了未使用/未记录的功能。Dice现在更轻量级且更快。
  • 修复了一个bug,当使用$rule->call时,它会在每次调用方法时使用构造函数上的替换规则。
  • 更新了Dice文档以使用简写数组语法。

01/03/2014

  • 为Xml Loader和Loader Callback类添加了测试用例。
  • 添加了JSON loader + 测试用例。
  • 将所有测试用例添加到测试套件中。
  • 迁移到PHP5.4数组语法。PHP5.3兼容版本现在可在PHP5.3分支中找到。
  • 修复了一个问题,即使用命名实例会在每次创建类时触发自动加载器,并使用无效的类名。

28/02/2014

  • 添加了基本命名空间支持。文档更新将很快完成。同时,将XML加载器移动到其自己的文件中,如果您正在使用它,需要单独包含它。
  • 请注意:更改与旧版本不兼容。但是,通过以下查找/替换操作可以轻松修复它们:
	new Dice => new \Dice\Dice
	new DiceInstance => new \Dice\Instance
	new DiceRule => new \Dice\Rule