gin0115/dice

Dice 是一个针对 PHP 的极简依赖注入容器(DIC)。请注意:3.0 及以上版本仅兼容 PHP 7.0。2.0 分支兼容 PHP 5.6。

4.1.0 2023-03-22 16:03 UTC

README

Dice 是一个专注于轻量级和快速,尽可能减少配置的 PHP 依赖注入容器。

项目目标

  1. 轻量级,不是一个拥有数十个文件的庞大库(Dice 是一个 100 行的类),但支持比复杂容器更多(甚至全部)的功能

  2. “即用即用”。基本功能应该可以零配置工作

  3. 当需要配置时,它应该尽可能简单、可重用,并且易于使用。

  4. 速度!(见 性能部分

安装

只需将轻量级的 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 及以上版本,有 Dice 的存档版本支持 PHP 5.6,但不再维护。

性能

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 实例并重新配置的 可变性相关的问题。唯一的区别是,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加载器变得多余,已经删除了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')));

不兼容的更改

  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

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

之前只使用命名实例的规则。

要恢复旧行为,请在命名实例上设置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现在更加轻量级和快速。
  • 修复了一个错误,当使用$rule->call时,它会使用构造函数上每个调用的替换规则
  • 更新了Dice文档,以使用简写数组语法

01/03/2014

  • 添加了对Xml加载器和Loader Callback类的测试用例
  • 添加了JSON加载器+测试用例
  • 将所有测试用例添加到测试套件中
  • 迁移到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