在PHP项目中设置依赖项注入

在PHP项目中设置依赖项注入,php,dependency-injection,Php,Dependency Injection,我试图在PHP中理解依赖注入的概念。我理解依赖注入用于“预加载”所有必要参数、函数和对象的基本原理。。运行操作所需的任何东西 然而,当我尝试在测试MVC上实现它时,我感觉我除了转换数据之外什么都没做 我写了一个小例子来说明我是如何做到这一点的。如果有人能告诉我我做错了什么 另外,我知道框架通常应用的依赖注入容器,但是如果我不能掌握它的基本知识,那么使用这样的容器是没有意义的 例如: <?php class database_test { public function __con

我试图在PHP中理解依赖注入的概念。我理解依赖注入用于“预加载”所有必要参数、函数和对象的基本原理。。运行操作所需的任何东西

然而,当我尝试在测试MVC上实现它时,我感觉我除了转换数据之外什么都没做

我写了一个小例子来说明我是如何做到这一点的。如果有人能告诉我我做错了什么

另外,我知道框架通常应用的依赖注入容器,但是如果我不能掌握它的基本知识,那么使用这样的容器是没有意义的

例如:

<?php

class database_test
{
    public function __construct($DB_con_info)
    {
        try {
            $dsn = "mysql:host=" . $DB_con_info['host'] .
                ";dbname=" . $DB_con_info['dbname'] .
                ";charset=" . $DB_con_info['charset'];
            echo 'database connection set -> ';

            $this->dbc = new PDO ($dsn, $DB_con_info['username'], $DB_con_info['password']);
            $this->dbc->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (PDOException $e) {
            echo "conn failed msg :  " . $e->fetMessage();
        }
    }
}

class model_interface extends database_test
{
    protected $dbc;

    protected $DB_con_info = array(
        'driver' => 'mysql',
        'host' => 'localhost',
        'dbname' => 'mvc_db',
        'username' => 'root',
        'password' => '',
        'charset' => 'utf8mb4'
    );

    //depende_injection
    public function __construct()
    {
        parent::__construct($this->DB_con_info);
        echo 'model_interface set -> ';
    }

    public function __destruct()
    {
        $this->dbc = null;
    }

    public function add($username, $last_name)
    {
        $sth = $this->dbc->prepare('INSERT INTO test (name, last_name ) VALUES (?,?)');
        $sth->execute([$username, $last_name]);
    }
}

class controller_test
{
    protected function __construct($name)
    {
        $this->view = new view();
        $this->model = $this->loadModel($name);
    }

    protected function loadModel($model)
    {
        //require the php file with the model class (test_model) in it
        require_once 'models/' . $model . '_model.php';
        //$model= test_model;
        $model = $model . '_model';

        //return new object of class test_model
        return new $model();
    }
}

class test_model extends model_interface
{

    private $model_interface_functions;

    //depende_injection
    public function __construct()
    {
        $this->model_interface_functions = new model_interface;
        echo 'model_interface_functions set ->';
    }

    public function __destruct()
    {
        $this->model_interface_functions = null;
    }

    public function test2()
    {
        $name = 'name';
        $last_name = 'last_name';
        $this->model_interface_functions->add($name, $last_name);
    }
}

class Test extends controller_test
{
    protected $model;
    protected $view;

    //depende_injection
    public function __construct()
    {
        echo 'setting depende_injection<br>';
        parent::__construct('test');
        echo 'all dependencies set ->';
    }

    public function test()
    {
        echo 'test controller <br>';
        $this->model->test2();
    }

    public function __destruct()
    {
        $this->model = null;
        $this->view = null;
    }

    public function index()
    {
        $this->view->render('test', 'index');
    }
}

这个简单的测试有很多代码。但我觉得你把事情弄得太复杂了。依赖注入仅仅意味着传递到所需的内容。因此,例如,如果您有一个需要访问数据库的存储库类,请传入一个完全构造的满足该要求的对象。然后,DIC简化了所有对象的构造。就是这样。没有必要让所有的类都互相扩展(不管怎样,没有它更好)。如果类不是真正的接口,请不要调用类
something\u interface
。)我不是这样做的吗?model_接口(我知道,但有必要将其命名为model->之外的其他名称,应该是model_lib,但它现在就是这样)需要一个db连接,以便构造函数创建它。测试控制器需要一个test_模型对象(至少其中的函数),以便构造函数创建它,依此类推。我知道它到处都是,但是,基本原则是否成立。如果是这样,下一步将是为所有依赖项创建处理该类的类。但是如果我错过了基本概念,那么这样做就没有意义了。另外,谢谢你的意见:)我不认为这是你在做的。例如,
model\u interface
扩展了
database\u test
,并要求传入连接信息。然后在内部使用该信息调用父构造函数。相反,不要从
database\u test
扩展,而是要求将该类型的对象传递到
model\u接口中。例如:
class model\u interface{public function\u构造(database\u test$dbc){$this->dbc=$dbc;}}
这就是我的意思,不要扩展所有内容。好的。我确实理解这一点。然而。这条路是走的(在我看来)。引导程序(调用什么控制器和方法)->that_控制器(创建对象以呈现视图和加载模型)->model_lib->database。难道你不想让我通过数据库连接吗?作为回报,我是否需要事先建造db conn?我相信只有模型库才能与数据库类对话?我明白如果我问得太多,如果你不想解释,请给我指一些材料,我会自己研究。我认为应该避免在这里进行长时间的讨论,这些评论迟早会被删除,但现在:是的,你说的对,你实际上需要事先构建所有东西(或者至少是在需要时,但在消费者之外)。这显然变得相当困难,因此人们使用DI容器。但为了使其简短、易读,并且不将MVC与DI混合,两者都是独立的概念。