You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:10:37