Symfony4:如何通过继承控制器复用路由等通用控制器注解
解决方案:通过基础父控制器复用类级注解
这问题我之前在项目里也碰到过,Symfony里用控制器继承来复用类级注解确实是个高效的方案,具体操作步骤如下:
1. 创建通用基础父控制器
先新建一个抽象的基础控制器(比如放在src/Controller/目录下),把你需要重复使用的类级注解都定义在这里:
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Component\Security\Core\Annotation\Security; /** * @Route("/pro/{uniqid}") * @ParamConverter("company", options={"mapping":{"uniqid" = "uniqid"}}) * @Security("is_granted(constant('App\\Security\\Voter\\CompanyVoter::VIEW'), company)") */ abstract class BaseAdminController extends Controller { // 这里还可以添加通用业务方法,比如获取当前公司的快捷方法、通用模板渲染逻辑等 }
把类设为abstract是为了避免直接实例化它,符合基础类的设计原则。
2. 让业务控制器继承基础类
现在你的AdminController只需要继承这个基础类,去掉重复的类注解,只保留自身的方法注解即可:
<?php namespace App\Controller; use Symfony\Component\HttpFoundation\Response; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; /** * @package App\Controller */ class AdminController extends BaseAdminController { /** * @Route("/admin/users/", name="users") * @return Response */ public function users(\App\Entity\Company $company) { // 这里可以直接使用$company变量,ParamConverter已经自动完成注入 return $this->render('admin/users.html.twig', [ 'company' => $company ]); } }
关键注意事项
- 注解继承支持:Symfony的
@Route、@ParamConverter、@Security这些注解天然支持继承,父类的类级注解会自动应用到所有子类上。 - 灵活覆盖注解:如果某个子控制器需要修改父类的配置(比如不同的路由前缀),直接在子类的类上重新声明对应的注解即可,子类注解会覆盖父类的配置。
- 简化参数注入:你可以直接在子类方法参数里声明
Company $company,ParamConverter会自动完成对象注入,不需要手动从请求中获取。
以后新建其他需要相同类注解的控制器(比如AdminProductController、AdminOrderController),只需要继承BaseAdminController就行,再也不用重复写那些繁琐的注解啦!
内容的提问来源于stack exchange,提问作者Boris Le Méec
相关产品推荐
相关产品推荐

