Symfony2中如何将变量传递至自定义503错误页面?
解决Symfony2 503错误页无法接收控制器传递变量的问题
兄弟,这个问题我太熟了!Symfony2里503错误的处理逻辑和403、404这类常规错误真的不一样,你遇到的变量不生效的问题,根源是503属于维护模式专属的响应,默认会绕过你写的业务控制器,直接渲染错误模板,所以你通过myController传的myDate根本没被模板接收到。下面给你两个靠谱的解决方案:
方案一:用事件监听器注入变量(推荐,符合Symfony架构)
这个方法是通过监听kernel.exception事件,在503异常触发时手动给模板传递变量,完全适配Symfony的异常处理流程。
1. 创建异常监听器类
// src/MyBundle/EventListener/ExceptionListener.php namespace MyBundle\EventListener; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpFoundation\Response; use Twig\Environment; class ExceptionListener { private $twig; public function __construct(Environment $twig) { $this->twig = $twig; } public function onKernelException(GetResponseForExceptionEvent $event) { $exception = $event->getException(); // 只处理503服务不可用异常 if ($exception instanceof HttpException && $exception->getStatusCode() === Response::HTTP_SERVICE_UNAVAILABLE) { // 这里替换成你获取$startDate的逻辑,比如从服务、配置或数据库读取 $startDate = new \DateTime('2024-01-01'); // 手动渲染503模板并注入变量 $responseContent = $this->twig->render( 'TwigBundle:Exception:error503.html.twig', ['myDate' => $startDate->format('Y-m-d H:i:s')] ); $event->setResponse(new Response($responseContent, Response::HTTP_SERVICE_UNAVAILABLE)); } } }
2. 注册监听器到服务容器
打开app/config/services.yml,添加以下配置:
services: my_bundle.exception_listener: class: MyBundle\EventListener\ExceptionListener arguments: ['@twig'] tags: - { name: kernel.event_listener, event: kernel.exception, method: onKernelException }
3. 正确触发503异常
注意:不要直接在控制器里渲染503模板,而是要抛出503异常,这样监听器才能捕获到:
// myController.php use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpFoundation\Response; public function someAction() { // 当服务不可用时,抛出503异常 throw new HttpException(Response::HTTP_SERVICE_UNAVAILABLE, '服务暂时不可用'); }
方案二:设置Twig全局变量(适合变量全局可用的场景)
如果myDate是一个全局通用的变量(比如从配置文件读取的维护开始时间),可以直接把它设为Twig全局变量,这样所有模板都能直接使用:
打开app/config/config.yml,在twig节点下添加全局变量配置:
twig: globals: myDate: '%maintenance_start_date%' # 假设你在parameters.yml里定义了这个参数
然后在app/config/parameters.yml里定义参数:
parameters: maintenance_start_date: '2024-01-01 10:00:00'
这样你的error503.html.twig模板就能直接使用myDate变量,不需要任何控制器传递。
为什么403/404能正常传参?
因为403、404这类常规异常,Symfony会走默认的异常控制器(或你自定义的twig.exception_controller)来渲染模板,这个过程会允许你传递变量;但503是维护模式下的特殊响应,默认会跳过这个流程,直接渲染模板,所以你原来的控制器传参方式无效。
内容的提问来源于stack exchange,提问作者doulouM
相关产品推荐
相关产品推荐

