在php项目开发中,随着业务复杂度提升,类之间的依赖关系会越来越繁琐,手动实例化依赖类不仅会增加代码量,还会提升模块间的耦合度。PHP-DI是一个功能完善的php依赖注入容器,支持自动依赖注入,能够帮我们简化依赖管理流程。

PHP-DI的安装与基础配置
首先需要通过composer安装PHP-DI容器,执行以下命令完成安装:
composer require php-di/php-di
安装完成后,我们可以创建一个基础的容器实例,默认情况下PHP-DI会自动扫描类的构造函数,完成依赖的自动注入:
<?php require_once 'vendor/autoload.php'; use DIContainerBuilder; // 创建容器构建器 $containerBuilder = new ContainerBuilder(); // 构建容器实例 $container = $containerBuilder->build();
定义基础类与自动依赖注入示例
我们先定义两个简单的业务类,模拟依赖关系。第一个是日志处理类:
<?php
// 日志接口
interface LoggerInterface
{
public function log(string $message): void;
}
// 文件日志实现类
class FileLogger implements LoggerInterface
{
public function log(string $message): void
{
echo "文件日志:" . $message . PHP_EOL;
}
}
再定义一个用户服务类,依赖日志接口:
<?php
class UserService
{
private LoggerInterface $logger;
// 构造函数依赖LoggerInterface
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
public function createUser(string $username): void
{
$this->logger->log("创建用户:" . $username);
}
}
此时我们无需手动实例化FileLogger并传入UserService,直接通过容器获取UserService实例即可,容器会自动注入FileLogger依赖:
<?php
require_once 'vendor/autoload.php';
use DIContainerBuilder;
$containerBuilder = new ContainerBuilder();
$container = $containerBuilder->build();
// 直接获取UserService实例,容器自动注入FileLogger
$userService = $container->get(UserService::class);
$userService->createUser("张三");
自定义依赖绑定规则
如果接口有多个实现类,或者需要自定义实例化逻辑,我们可以通过容器的定义配置来绑定依赖关系。比如我们新增一个数据库日志实现类:
<?php
class DatabaseLogger implements LoggerInterface
{
public function log(string $message): void
{
echo "数据库日志:" . $message . PHP_EOL;
}
}
我们可以通过addDefinitions方法定义依赖绑定规则,指定LoggerInterface使用DatabaseLogger实现:
<?php
require_once 'vendor/autoload.php';
use DIContainerBuilder;
$containerBuilder = new ContainerBuilder();
// 定义依赖绑定规则
$containerBuilder->addDefinitions([
LoggerInterface::class => DIcreate(DatabaseLogger::class)
]);
$container = $containerBuilder->build();
$userService = $container->get(UserService::class);
$userService->createUser("李四");
自动依赖注入的优势
使用PHP-DI实现自动依赖注入后,我们的业务代码不需要再关心依赖类的实例化过程,只需要声明依赖即可。对比手动实例化依赖的方式:
- 手动方式需要写
$logger = new FileLogger(); $userService = new UserService($logger);,新增依赖时还要修改实例化逻辑 - 使用PHP-DI后,只需要通过容器获取目标类,所有依赖自动处理,降低代码耦合度
- 后续替换依赖实现时,只需要修改容器定义,不需要改动业务类的代码,提升代码可维护性
常见使用注意事项
在使用PHP-DI时需要注意以下几点:
1. 类的依赖最好基于接口声明,而不是具体实现类,这样更方便后续替换依赖
2. 如果类的构造函数有非对象类型的必填参数,需要提前在容器定义中指定参数值
3. 生产环境建议开启容器的编译缓存,提升容器性能
通过以上方式,我们就可以在php项目中熟练使用PHP-DI容器,通过自动依赖注入简化代码编写,提升项目的整体架构质量。