如何通过PHP DI获取Logger注入目标类的类名作为channel参数?
解决方案:通过PHP DI上下文动态注入目标类名作为Logger的Channel参数
要实现Logger自动获取依赖它的目标类名作为channel参数,可利用PHP DI的工厂函数+解析上下文来实现,具体步骤如下:
核心实现代码
修改你的PHP DI配置文件,使用工厂函数替代直接的autowire,通过DefinitionContext获取当前注入的目标类信息:
use DI\ContainerInterface; use DI\Definition\DefinitionContext; return [ // 直接绑定Logger类的配置 Logger::class => function (ContainerInterface $container, DefinitionContext $context) { // 获取当前被注入的目标类的完整类名 $targetClassName = $context->getTarget()->getName(); return new Logger($targetClassName); }, // 绑定到接口(如SomeLoggerInterface)的配置 SomeLoggerInterface::class => function (ContainerInterface $container, DefinitionContext $context) { $targetClassName = $context->getTarget()->getName(); return new Logger($targetClassName); }, ];
原理说明
DefinitionContext是PHP DI提供的上下文对象,在解析依赖的过程中,它能获取到当前正在被实例化的目标类的反射信息。- 调用
$context->getTarget()->getName()即可拿到目标类的完整类名(比如UsingLogger),直接传入Logger的构造函数作为channel参数。
验证效果
当容器解析UsingLogger类时,会自动为其注入的Logger实例传入UsingLogger作为channel参数,和手动实例化的效果完全一致:
// 容器自动解析,无需手动创建Logger $usingLogger = $container->get(UsingLogger::class); // 此时$usingLogger->logger的channel参数值为"UsingLogger"
注意事项
- 确保使用的PHP DI版本支持
DefinitionContext特性(推荐v6.x及以上版本)。 - 如果目标类依赖的是接口(如
SomeLoggerInterface),上述配置同样有效,getTarget()会返回当前被解析的具体类(如UsingLogger)的反射对象。
内容的提问来源于stack exchange,提问作者Kindlewing
相关产品推荐
相关产品推荐

