Symfony配置中使用::class引用FQCN实现编译期类存在校验
问题根因
你遇到的报错是因为!php/const标签仅支持读取PHP中实际定义的常量,而::class是PHP提供的语法糖,会在代码编译阶段被替换为对应类的全限定类名字符串,本身不属于常量定义,因此无法被!php/const识别。
可行实现方案
方案1:使用
!php/eval标签(YAML配置兼容)
Symfony的YAML配置支持!php/eval标签直接执行合法的PHP表达式,刚好可以解析::class语法,类不存在时会在容器编译阶段直接抛出错误,符合你的校验需求。修改后配置如下:
services: command.bus.my_middleware: class: App\Infrastructure\CommandBus\Middleware\MyMiddleware arguments: $ignoredExceptions: - !php/eval App\Exception\DownloadException::class - !php/eval App\Exception\InvalidImageException::class
注意:该标签仅会执行你写在配置里的固定表达式,配置文件本身属于可信环境,不存在安全风险。
方案2:改用PHP格式的服务配置
如果不想在YAML里使用PHP表达式,你可以直接将该服务的配置改为PHP格式,天然支持::class语法,同时IDE还能提供自动补全、类不存在提前标红的能力,是兼容性最好的方案:
// config/services.php use App\Infrastructure\CommandBus\Middleware\MyMiddleware; use App\Exception\DownloadException; use App\Exception\InvalidImageException; return static function (\Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator $configurator) { $services = $configurator->services(); $services->set('command.bus.my_middleware', MyMiddleware::class) ->arg('$ignoredExceptions', [ DownloadException::class, InvalidImageException::class, ]); };
方案3:自定义编译器校验逻辑(不推荐)
如果以上两种方案都不适用,你可以编写自定义的Symfony编译器Pass,在容器编译阶段遍历对应服务的参数,逐个校验类是否存在,不过该方案需要额外编写业务无关的代码,性价比很低,不推荐使用。
内容的提问来源于stack exchange,提问作者BenMorel
相关产品推荐
相关产品推荐

