如果您有多个依赖项需要处理,那么可以使用 DI 容器来解决。
DI 容器可以是由您需要的各种依赖对象构成的对象或数组,这些对象被传递给构造函数并解包。
假设您需要一个配置对象、一个数据库连接和一个传递给每个类的客户端信息对象。您可以创建一个包含它们的数组:
// Assume each is created or accessed as a singleton, however needed...
// This may be created globally at the top of your script, and passed into each newly
// instantiated class
$di_container = array(
'config' = new Config(),
'db' = new DB($user, $pass, $db, $whatever),
'client' = new ClientInfo($clientid)
);
并且您的类构造函数接受 DI 容器作为参数:
class SomeClass {
private $config;
private $db;
private $client;
public function __construct(&$di_container) {
$this->config = $di_container['config'];
$this->db = $di_container['db'];
$this->client = $di_container['client'];
}
}
您也可以将 DI 容器创建为类本身,并使用单独注入其中的组件类来实例化它,而不是像上面那样创建一个数组(这很简单)。使用对象而不是数组的一个好处是,默认情况下它将通过引用传递给使用它的类,而数组是通过值传递(尽管数组中的对象仍然是引用)。
编辑
在某些方面,对象比数组更灵活,尽管最初的代码更复杂。
容器对象也可以在其构造函数中创建/实例化包含的类(而不是在外部创建它们并传入它们)。这可以为使用它的每个脚本节省一些编码,因为您只需要实例化一个对象(它本身会实例化其他几个对象)。
Class DIContainer {
public $config;
public $db;
public $client;
// The DI container can build its own member objects
public function __construct($params....) {
$this->config = new Config();
// These vars might be passed in the constructor, or could be constants, or something else
$this->db = new DB($user, $pass, $db, $whatever);
// Same here - the var may come from the constructor, $_SESSION, or somewhere else
$this->client = new ClientInfo($clientid);
}
}