gpt4 book ai didi

php - 如何构建 PHP 依赖注入(inject)容器

转载 作者:行者123 更新时间:2023-12-03 00:09:58 24 4
gpt4 key购买 nike

我最近了解了在 PHP 应用程序中使用依赖注入(inject) (DI) 的优势。但是,我仍然不确定如何为依赖项创建容器,或者我是否应该为我正在构建的在线论坛使用 DI。

下面的代码是我根据here中学到的例子制作的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();

我有几个问题:

1) 我应该在哪里实例化我的注入(inject)依赖项,例如 $database、$session 等?它是在容器类之外,还是在容器的构造函数内部。

2) 如果我需要在其他类中创建 User 类的多个实例怎么办?我无法注入(inject)先前实例化的 $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();
while($row = $st->fetch()) {
$friend = ioc::newUser($row['user_id']);
$friend->get_user_name();
$friend->get_profile_picture();
}
}
}

3) 我想知道我是否应该采用 DI,因为我知道我必须重写所有以前的代码。我以前一直依赖于在initialize.php 中实例化的全局变量,该变量包含在我的所有文件中。

在我看来,DI 会产生大量开销,并且在某些情况下它无法使用(如我的#2 示例)。以下网站来自一位开发人员,他列举了许多不使用 DI 的充分理由。他的论点有什么道理吗?或者我只是使用 DI 错误? check this link .

最佳答案

Where should I instantiate my injected dependencies, such as $database, $session, etc? Would it be outside the container class, or inside the container's constructor.

理想情况下,您的数据库连接和 session 将被引导。正确的 DI 需要一个基本对象的实例,所有内容都注册到该实例中。因此,以 IOC 类为例,您需要创建它的实例 ($ioc = new IOC();),然后您需要某种服务提供者类

$ioc->register('database', new DatabaseServiceProvider($host, $user, $pass))

现在,每次您想要连接到数据库时,您只需传入 $ioc->get('database'); 一个非常粗略的示例,但我认为您可以看到这个想法基本上将所有内容存储在注册表中,并且没有任何内容是静态绑定(bind)的,这意味着您可以使用完全不同的设置创建另一个 $ioc 实例,从而可以轻松创建连接以表示用于测试目的的不同数据库。

What if I need to create a multiple instances of the User class inside other classes? I can't inject the previously instantiated $user object because that instance is already being used. However, creating the multiple User instances inside of another class would violate the rules of DI.

这是一个常见问题,有多种不同的解决方案。首先,您的 DI 应显示登录用户和普通用户之间的区别。您可能想要注册您登录的用户,但不仅仅是任何用户。使您的用户类别正常并使用

$ioc->register('login-user', User::fetch($ioc->get('database'), $user_id));

现在 $ioc->get('login-user') 返回您的登录用户。然后,您可以使用 User->fetchAll($ioc->get('database')); 获取所有用户。

I'm wondering if I should even adopt DI, knowing that I have to rewrite all of my previous code. I've previously been relying on global variables that I instantiate in my initialize.php, which is included in all my files.

如果您需要重写所有代码以使用 DI,您可能不应该这样做。如果有时间的话,也许可以考虑创建一个新项目并使用一些旧代码。如果您的代码库很大,我建议您考虑将其分解为较小的项目,并使用 RESTFUL api 来获取和保存数据。编写 API 的好例子是将论坛搜索放入其自己的应用程序中/search/name?partial-name=bob 将返回其中包含 bob 一词的所有用户。您可以构建它并随着时间的推移使其变得更好,并在您的主论坛中使用它

我希望您理解我的回答,但如果您需要更多信息,请告诉我。

关于php - 如何构建 PHP 依赖注入(inject)容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14214408/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com