You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP依赖注入:是否应注入依赖注入容器(DIC)?

基于依赖注入的类结构实现示例

我来给你梳理下这个依赖注入风格的类结构实现,把核心框架代码和应用层使用逻辑清晰地展示出来:

框架代码(核心组件)

这部分是基础工具类,负责提供日志、数据库、Redis等基础能力,通过构造函数注入实现组件解耦:

Logger 类(简单日志组件)

负责基础的日志记录功能,是其他组件的核心依赖项:

class Logger {
    public function log(string $message): void {
        // 可按需扩展为写入文件、日志服务等实现
        echo "Log: {$message}\n";
    }
}

Database 类(依赖注入 Logger)

数据库操作类,通过构造函数注入Logger来记录初始化、查询等关键操作日志:

class Database {
    private Logger $log;
    private string $dbConfig;

    // 构造函数注入Logger实例与数据库配置参数
    public function __construct(Logger $log, string $dbConfig) {
        $this->log = $log;
        $this->dbConfig = $dbConfig;
        $this->log->log("Database initialized with config: {$dbConfig}");
    }

    // 示例:执行SQL并记录操作日志
    public function query(string $sql): void {
        $this->log->log("Executing SQL query: {$sql}");
        // 实际的数据库查询逻辑写在这里
    }
}

Redis 类(依赖注入 Logger)

Redis缓存操作类,同样依赖Logger来记录连接、缓存操作等日志:

class Redis {
    private Logger $log;
    private string $redisHost;

    public function __construct(Logger $log, string $redisHost) {
        $this->log = $log;
        $this->redisHost = $redisHost;
        $this->log->log("Redis client connected to host: {$redisHost}");
    }

    // 示例:设置缓存并记录操作日志
    public function set(string $key, mixed $value): void {
        $this->log->log("Redis set operation for key: {$key}");
        // 实际的缓存设置逻辑写在这里
    }
}

业务逻辑类(注入所有核心组件)

业务层类,通过构造函数注入Logger、Database、Redis所有依赖,专注于业务逻辑实现:

class BusinessLogic {
    private Logger $log;
    private Database $db;
    private Redis $redis;

    // 一次性注入所有需要的依赖组件
    public function __construct(Logger $log, Database $db, Redis $redis) {
        $this->log = $log;
        $this->db = $db;
        $this->redis = $redis;
        $this->log->log("BusinessLogic component initialized successfully");
    }

    // 示例业务方法:结合缓存与数据库处理用户请求
    public function processUserRequest(int $userId): void {
        $this->log->log("Start processing request for user ID: {$userId}");
        
        // 先尝试从Redis获取缓存数据
        $this->redis->set("user_{$userId}", "sample_user_data");
        
        // 再执行数据库查询操作
        $this->db->query("SELECT * FROM users WHERE id = {$userId}");
    }
}

应用代码(业务层使用示例)

这部分是实际业务代码,负责实例化所有组件并组装依赖关系:

// 1. 先实例化最基础的Logger组件
$logger = new Logger();

// 2. 实例化Database和Redis,传入Logger实例作为依赖
$database = new Database($logger, "mysql:host=localhost;dbname=my_app");
$redisClient = new Redis($logger, "localhost:6379");

// 3. 实例化业务逻辑类,注入所有依赖组件
$businessService = new BusinessLogic($logger, $database, $redisClient);

// 4. 调用业务方法处理请求
$businessService->processUserRequest(456);

这种依赖注入方式的优势

  • 职责单一:每个类只负责自己的核心功能,Logger管日志,Database管数据库,业务类管业务逻辑
  • 易于测试:测试时可以轻松替换Logger为Mock对象,不用修改核心业务代码
  • 组件解耦:后续如果要更换数据库驱动或缓存服务,只需要修改对应组件类,不影响业务逻辑

内容的提问来源于stack exchange,提问作者779IDEAS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:38:18