PHP中的依赖注入:完整指南与示例

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

PHP 中的依赖注入简介



现代 PHP 开发离不开面向对象设计原则。其中一个能够构建灵活、可测试和可维护应用程序的关键模式是 Dependency Injection (DI) 或 依赖注入。



该模式的本质很简单:我们不直接在类内部创建依赖对象,而是从外部传入(注入)它们。这从根本上改变了应用程序的架构,使类独立于具体实现,并简化了测试过程。



在本文中,我们将探讨 PHP 中的 Dependency Injection 是什么,有哪些实现方式,以及如何使用 DI 容器来自动化这一过程。



问题:为什么没有 DI 不好?



来看一个典型示例。UserController 类负责处理与用户相关的请求。它通过 MysqlDatabase 类使用数据库:



<?php

class MysqlDatabase { public function query(string $sql): array { // ... 连接到 MySQL 并执行查询 return []; }}

class UserController { private MysqlDatabase $database;

public function __construct() { // 硬绑定到具体实现 $this->database = new MysqlDatabase(); }

public function listUsers(): array { return $this->database->query('SELECT * FROM users'); }}

$controller = new UserController();


这段代码有什么问题?



  • 高耦合度: UserController 硬绑定到 MysqlDatabase。如果我们想切换到 PostgreSQL 或使用文件存储,就必须修改控制器的代码。
  • 测试困难: 在单元测试中无法将数据库替换为模拟对象。每个测试都会访问真实数据库,速度慢且不方便。
  • 违反单一职责原则: 控制器不应该知道如何创建数据库连接。它的职责是处理请求。


解决这个问题的方法是应用控制反转(IoC)原则并使用 Dependency Injection。



PHP 中依赖注入的方式



有三种主要方式可以将依赖注入到类中:



1. 构造函数注入(Constructor Injection)



这是最常见且推荐的方式。依赖通过构造函数参数传入,通常保存为类的私有属性。



<?php

interface DatabaseInterface { public function query(string $sql): array;}

class MysqlDatabase implements DatabaseInterface { public function query(string $sql): array { // MySQL 的实现 return []; }}

class PostgresDatabase implements DatabaseInterface { public function query(string $sql): array { // PostgreSQL 的实现 return []; }}

class UserController { private DatabaseInterface $database;

// 依赖通过构造函数注入 public function __construct(DatabaseInterface $database) { $this->database = $database; }

public function listUsers(): array { return $this->database->query('SELECT * FROM users'); }}

// 使用$mysqlDb = new MysqlDatabase();$controller = new UserController($mysqlDb);

// 轻松切换到另一个数据库$postgresDb = new PostgresDatabase();$controller2 = new UserController($postgresDb);


优点: 依赖关系清晰可见,对象在有效状态下创建(依赖是必需的)。



2. Setter 注入(Setter Injection)



适用于可选依赖或当依赖

博客

书籍推荐