Symfony 4:通用类中如何自动注入字符串参数?
这个问题我之前碰到过,Symfony的Autowire对于动态字符串参数确实有点棘手——容器没法自动推断每个控制器需要的不同值。给你几个可行的解决方案,按复杂度从低到高来:
方案1:直接在控制器中实例化General类
最简单直接的方式:既然每个控制器需要的$route和$entity都是动态且唯一的,那就别把General注册为服务,直接在控制器里手动实例化:
// 你的控制器方法内 public function getDataAction() { // 根据当前控制器的需求传入对应参数 $general = new \App\General('/api/v1/your-specific-route', YourTargetEntity::class); // 调用General封装的逻辑,比如验证API密钥并返回数据 return $general->handleApiRequest(); }
这种方式完全绕开了依赖注入的限制,不需要在services.yaml里做任何额外配置,完美适配每个实例参数不同的场景。
方案2:用工厂类封装General的实例化(适合General有其他依赖的情况)
如果General内部还有其他需要依赖注入的服务(比如EntityManagerInterface、日志组件等),可以创建一个工厂类来兼顾DI管理和动态参数传递:
第一步:创建General工厂类
// src/GeneralFactory.php namespace App; use Doctrine\ORM\EntityManagerInterface; class GeneralFactory { private $entityManager; // 注入General需要的其他固定依赖 public function __construct(EntityManagerInterface $entityManager) { $this->entityManager = $entityManager; } // 对外暴露创建方法,接收动态参数 public function create(string $route, string $entityClass): General { return new General($route, $entityClass, $this->entityManager); } }
第二步:在控制器中使用工厂
// 控制器方法内 public function getDataAction(GeneralFactory $factory) { // 传入当前控制器专属的路由和实体类 $general = $factory->create('/api/v1/your-route', YourTargetEntity::class); // 执行封装逻辑 return $general->handleApiRequest(); }
Symfony默认会自动注册src/目录下的类为服务,所以GeneralFactory可以直接被Autowire注入控制器,既保留了DI管理固定依赖的便利,又能灵活传入动态参数。
方案3:从请求中动态获取路由(仅适用于路由与当前请求绑定的场景)
如果你的$route参数就是当前控制器对应的路由名称,可以通过请求栈直接获取,避免手动传入:
use Symfony\Component\HttpFoundation\RequestStack; public function getDataAction(RequestStack $requestStack) { $currentRouteName = $requestStack->getCurrentRequest()->attributes->get('_route'); $general = new General($currentRouteName, YourTargetEntity::class); // ...后续逻辑 }
但这种方式局限性大,只适用于$route等于当前请求路由的场景,不适合自定义路由参数的情况。
内容的提问来源于stack exchange,提问作者user11480180
相关产品推荐
相关产品推荐

