当前位置:首页 > PHP

php怎么实现依赖注入

2026-04-03 09:47:26PHP

依赖注入的实现方法

在PHP中实现依赖注入(Dependency Injection, DI)通常有以下几种方式:

构造函数注入

通过类的构造函数传递依赖对象。这是最常见的方式,适合强制依赖项。

class DatabaseService {
    private $connection;

    public function __construct(PDO $connection) {
        $this->connection = $connection;
    }
}

$connection = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
$databaseService = new DatabaseService($connection);

setter方法注入

通过setter方法设置依赖对象。适合可选依赖项或需要动态更换依赖的情况。

class Logger {
    private $writer;

    public function setWriter(WriterInterface $writer) {
        $this->writer = $writer;
    }
}

$logger = new Logger();
$logger->setWriter(new FileWriter());

接口注入

依赖项通过接口定义,实现类必须提供注入方法。

interface InjectLogger {
    public function inject(Logger $logger);
}

class UserService implements InjectLogger {
    private $logger;

    public function inject(Logger $logger) {
        $this->logger = $logger;
    }
}

使用容器实现DI

依赖注入容器可以自动管理对象的创建和依赖关系:

简单容器实现

class Container {
    private $services = [];

    public function register(string $name, callable $resolver) {
        $this->services[$name] = $resolver;
    }

    public function get(string $name) {
        if (!isset($this->services[$name])) {
            throw new Exception("Service not found: {$name}");
        }
        return $this->services[$name]($this);
    }
}

$container = new Container();
$container->register('db', function() {
    return new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
});
$container->register('userService', function($container) {
    return new UserService($container->get('db'));
});

使用现有DI框架

主流PHP框架都提供DI容器:

Laravel容器示例

// 绑定
app()->bind('mailer', function($app) {
    return new Mailer($app->make('config'));
});

// 解析
$mailer = app()->make('mailer');

Symfony容器示例

# services.yaml
services:
    App\Mail\Mailer:
        arguments: ['@mail.transport']

自动装配实现

现代框架支持基于类型提示的自动依赖解析:

php怎么实现依赖注入

class OrderService {
    public function __construct(
        private PaymentGateway $gateway,
        private LoggerInterface $logger
    ) {}
}

// 容器会自动解析并注入PaymentGateway和LoggerInterface的实现
$orderService = $container->get(OrderService::class);

最佳实践

  • 优先使用构造函数注入强制依赖
  • 对可选依赖使用setter注入
  • 遵循依赖倒置原则,依赖抽象而非具体实现
  • 对复杂项目使用成熟的DI容器
  • 避免服务定位器模式(Service Locator),它实际上是DI的反模式

通过合理使用依赖注入,可以提高代码的可测试性、可维护性和灵活性。

标签: php
分享给朋友:

相关文章

php实现文件上传

php实现文件上传

文件上传的基本实现 在PHP中实现文件上传需要使用$_FILES超全局数组处理上传的文件数据。表单必须设置enctype="multipart/form-data"属性,并采用POST方法提交。 创…

php实现购物车

php实现购物车

PHP实现购物车功能 购物车功能是电商网站的核心模块之一,通常涉及商品添加、删除、数量修改和结算等操作。以下是使用PHP实现购物车功能的几种方法。 使用Session存储购物车数据 Session是…

php实现表单

php实现表单

PHP 表单基础实现 创建一个简单的 PHP 表单需要 HTML 表单结构和 PHP 处理脚本。以下是一个完整的示例: HTML 表单部分 (form.html) <form action=…

php实现注册

php实现注册

注册功能实现步骤 数据库准备 创建用户表,包含字段如id、username、password、email等。示例SQL: CREATE TABLE users ( id INT AUTO_I…

php怎么实现登录功能

php怎么实现登录功能

数据库准备 创建用户表存储登录信息,通常包括用户名、密码(需加密)等字段。示例SQL: CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY…

php 实现下载apk

php 实现下载apk

使用 PHP 实现 APK 文件下载 通过 PHP 实现 APK 文件下载的核心是设置正确的 HTTP 头信息,并输出文件内容。以下是一个完整的实现方法。 设置 HTTP 头信息 确保客户端正确识别…