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

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

I hear people talking about dependency injection and the benefit of it all the time, but I don't really understand it.

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

I'm wondering if it's a solution to the "I pass database connections as arguments all the time" problem.

我尝试阅读维基百科关于它的条目,但该示例是用 Java 编写的,所以我不能完全理解它试图阐明的区别.( http://en.wikipedia.org/wiki/Dependency_injection).

I tried reading wikipedia's entry on it, but the example is written in Java so I don't solidly understand the difference it is trying to make clear. ( http://en.wikipedia.org/wiki/Dependency_injection ).

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

I read this dependency-injection-in-php article ( http://www.potstuck.com/2009/01/08/php-dependency-injection/ ), and it seems like the objective is to not pass dependencies to an object directly, but to cordon off the creation of an object along with the creation of it's dependencies. I'm not sure how to apply that in a using php functions context, though.

另外,下面是依赖注入,我是否应该费心尝试在函数上下文中进行依赖注入?

Additionally, is the following Dependency Injection, and should I bother trying to do dependency injection in a functional context?

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

Version 1: (the kind of code that I create, but don't like, every day)

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

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

Version 2: (don't have to pass a database connection, but perhaps not dependency injection?)

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:(对象"/数据的创建是分开的,数据库代码是静止的,所以这可能算作依赖注入?)

Version 3: (the creation of the "object"/data is separate, and the database code is still, so perhaps this would count as dependency injection?)

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();

有没有人有很好的资源或只是洞察力,使方法和好处 - 晶莹剔透?

Anyone have a good resource or just insight that makes the method and benefit -crystal- clear?

推荐答案

依赖注入是一个大词,表示我的构造函数中有更多参数".

Dependency injection is a big word for "I have some more parameters in my constructor".

当你不喜欢全局变量时,这就是你在可怕的 Singleton 浪潮之前所做的:

It's what you did before the awfull Singleton wave when you did not like globals :

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

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

现在,诀窍是使用单个类来管理您的依赖项,就像这样:

Now, the trick is to use a single class to manage your dependencies, something like that :

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() 添加到您的用户类.其余代码无需更改.

You must think you just another class and more complexity. But, your user class may need something to log messages like lot of other classes. Just add a getMessageHandler function to your dependency container, and some $this->_messages = $di->getMessageHandler() to your user class. Nothing to change in the rest of your code.

你会得到很多关于 symfony 的文档

相关文章