如何在简单的php函数中使用“依赖注入”,我应该打扰吗?

我听到人们一直在谈论依赖注入及其好处,但我并不真正理解它。

我想知道这是否是“我一直将数据库连接作为参数传递”问题的解决方案。

我试着阅读维基百科的条目,但这个例子是用Java写的,所以我没有真正理解它试图弄清楚的区别。( http://en.wikipedia.org/wiki/Dependency_injection )。

我读了这篇依赖注入php的文章(http://www.potstuck.com/2009/01/08/php-dependency-injection/),似乎目标不是直接将依赖关系传递给对象,而是阻止对象的创建以及其依赖关系的创建。不过,我不确定如何在使用php函数的上下文中应用它。

此外,以下是依赖关系注入,我应该在功能上下文中尝试进行依赖关系注入吗?

版本1:(我每天创建但不喜欢的那种代码)

function get_data_from_database($database_connection){
    $data = $database_connection->query('blah');
    return $data;
}

版本2:(不必传递数据库连接,但也许不需要依赖注入?

function get_database_connection(){
    static $db_connection;
    if($db_connection){
        return $db_connection;
    } else {
        // create db_connection
      ...
    }
}

function get_data_from_database(){
   $conn = get_database_connection();
   $data = $conn->query('blah');
   return $data;
}

$data = get_data_from_database();

版本3:(“对象”/数据的创建是分开的,数据库代码仍然是,所以也许这可以算作依赖注入?

function factory_of_data_set(){
    static $db_connection;
    $data_set = null;
    $db_connection = get_database_connection();
    $data_set = $db_connection->query('blah');
    return $data_set;
}

$data = factory_of_data_set();

任何人都有一个很好的资源或只是洞察力,使方法和好处 - 水晶 - 清晰?


答案 1

依赖注入是“我的构造函数中还有更多参数”的一个大词。

这是你在可怕的辛格尔顿浪潮之前所做的,当你不喜欢全局时:

<?php
class User {
    private $_db;
    function __construct($db) {
        $this->_db = $db;
    }
}

$db   = new Db();
$user = new User($db);

现在,诀窍是使用单个类来管理您的依赖项,如下所示:

class DependencyContainer 
{
    private _instances = array();
    private _params = array();

    public function __construct($params)
    {
        $this->_params = $params;
    }

    public function getDb()
    {
        if (empty($this->_instances['db']) 
            || !is_a($this->_instances['db'], 'PDO')
        ) {
            $this->_instances['db'] = new PDO(
                $this->_params['dsn'],
                $this->_params['dbUser'], 
                $this->_params['dbPwd']
            );
        }
        return $this->_instances['db'];
    }
}

class User
{
    private $_db;
    public function __construct(DependencyContainer $di)
    {
         $this->_db = $di->getDb();
    }
}

$dependencies = new DependencyContainer($someParams);
$user = new User($dependencies);

你必须认为你只是另一个阶级和更复杂的。但是,您的用户类可能需要一些东西来记录消息,就像许多其他类一样。只需将 getMessageHandler 函数添加到依赖项容器中,并将一些函数添加到用户类中即可。在代码的其余部分没有任何更改。$this->_messages = $di->getMessageHandler()

您将在symfony的文档上获得很多信息


答案 2

您的第一个示例 IS 依赖性注入,您正在将数据库对象的依赖关系注入到函数中。

Sarah说过这不是,但imo是的,我相信她正在考虑依赖注入容器,这是下一个层次:

http://components.symfony-project.org/dependency-injection/trunk/book/02-Dependency-Injection-Containers


推荐