我正在尝试用PHP编写TDD样式,而我最大的绊脚石之一(除了缺乏一个像样的IDE)是我必须将我自己的黑客攻击IoC容器才能正确地注入我所有的模拟对象.
有没有人在PHP中使用过Ioc容器?我所能找到的就是PHP IOC上那些烦人的phpclasses.org,它似乎几乎没有任何文档,也没有太多关注.
我最近了解到在我的PHP应用程序中使用依赖注入(DI)的优点.但是,我仍然不确定如何为依赖项创建容器,或者我是否应该在我正在构建的在线论坛中使用DI.
以下代码是我根据我从这里学到的例子制作的DI容器的版本.
class ioc {
var $db;
var $session;
var $user_id;
static function newUser(static::$db, static::$user_id) {
$user = new User($db, $user_id);
return $user;
}
static function newLogin(static::$db, static::$session) {
$login = new Login($db, $session);
return $login;
}
}
$user = ioc::newUser();
$login = ioc::newLogin();
Run Code Online (Sandbox Code Playgroud)
我有几个问题:
1)我应该在哪里实例化我注入的依赖项,例如$ database,$ session等?它是在容器类之外,还是在容器的构造函数内部.
2)如果我需要在其他类中创建User类的多个实例,该怎么办?我无法注入先前实例化的$ user对象,因为该实例已被使用.但是,在另一个类中创建多个User实例会违反DI规则.例如:
class Users {
function __construct($db, $user_id) {
$this->db = $db;
$this->user_id = $user_id;
}
function create_friends_list() {
$st = $this->$db->prepare("SELECT user_id FROM friends WHERE user_id = $this->user_id");
$st->execute(); …Run Code Online (Sandbox Code Playgroud) 我已经使用了Dice PHP DI容器很长一段时间,它在注入依赖项的简单性方面似乎是最好的.
来自骰子文档:
class A {
public $b;
public function __construct(B $b) {
$this->b = $b;
}
}
class B {
}
$dice = new \Dice\Dice;
$a = $dice->create('A');
var_dump($a->b); //B object
Run Code Online (Sandbox Code Playgroud)
但是,当您必须使用直接相互依赖的对象时,由于无限循环,finall结果是服务器错误.
例:
class A {
public $b;
public function __construct(B $b) {
$this->b = $b;
}
}
class B {
public $a;
public function __construct(A $a) {
$this->a = $a;
}
}
Run Code Online (Sandbox Code Playgroud)
Dice的作者说没有办法从A或B类构造一个对象.如:
作者说,这个限制涉及所有 DI容器!