Symfony 4命令中Locale注入失败问题解决求助
解决Symfony 4命令中Locale注入的问题
这个报错的根源很明确:命令运行在CLI环境下,没有HTTP请求,所以request_stack的getCurrentRequest()返回null,调用getLocale()自然就触发了错误。下面给你几个实用的解决方案:
方案一:修改依赖绑定,兼容CLI和Web环境
直接在services.yaml的绑定逻辑里加个判断,当请求不存在时使用默认的%locale%参数,这样Web环境用请求的Locale,CLI环境用默认值:
parameters: locale: 'en' app_locales: en|fr|de|es|pt services: _defaults: autowire: true autoconfigure: true bind: # 新增判断:有请求则用请求的Locale,否则用默认值 $locale: "@=service('request_stack').getCurrentRequest() ? service('request_stack').getCurrentRequest().getLocale() : '%locale%'" $listLocales: '%app_locales%' # 其他配置保持不变 App\: resource: '../src/*' exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}' App\Repository\: resource: '../src/Repository'
这样你的仓库在Web和命令环境下都能正常获取到Locale,不需要修改任何业务代码。
方案二:给命令添加Locale选项,支持自定义指定
如果需要让命令可以灵活指定Locale,可以给命令添加一个可选参数,同时注入默认Locale作为 fallback:
1. 修改命令代码
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; class FooCommand extends Command { protected static $defaultName = 'app:fetch-foo'; private $someRepository; private $defaultLocale; public function __construct(SomeRepository $someRepository, string $defaultLocale) { $this->someRepository = $someRepository; $this->defaultLocale = $defaultLocale; parent::__construct(); } protected function configure() { $this ->setDescription('Fetch foo data with optional locale') ->addOption( 'locale', null, InputOption::VALUE_OPTIONAL, 'Locale to use for the query', $this->defaultLocale // 默认使用配置里的locale ); } protected function execute(InputInterface $input, OutputInterface $output) { // 如果你的仓库支持动态设置Locale,在这里更新 $this->someRepository->setLocale($input->getOption('locale')); $demoData = $this->someRepository->getFoo(); var_dump($demoData); return Command::SUCCESS; } }
2. 确保仓库支持动态设置Locale
如果你的AbstractRepository还没有setLocale方法,需要添加:
abstract class AbstractRepository { protected $locale; public function __construct(string $locale) { $this->locale = $locale; } // 新增动态设置方法 public function setLocale(string $locale): void { $this->locale = $locale; } }
这样运行命令时,可以指定自定义Locale:
php bin/console app:fetch-foo --locale=fr
方案三:针对命令单独绑定Locale
如果只想给命令环境设置固定的Locale,可以在services.yaml里给命令单独配置绑定:
services: # 原来的_defaults保持不变 _defaults: autowire: true autoconfigure: true bind: $locale: "@=service('request_stack').getCurrentRequest().getLocale()" $listLocales: '%app_locales%' # 给命令单独绑定默认Locale App\Command\: resource: '../src/Command' bind: $locale: '%locale%' # 其他配置保持不变 App\: resource: '../src/*' exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php,Command}' App\Repository\: resource: '../src/Repository'
注意这里要把Command目录从App\的资源排除,避免继承全局的绑定。
总结
最推荐的是方案一,它能无缝兼容Web和CLI环境,不需要额外修改业务代码;如果需要命令支持自定义Locale,方案二更灵活。
内容的提问来源于stack exchange,提问作者Astro-Otter
相关产品推荐
相关产品推荐

