显示特定路由而不是错误页面(404)-Symfony2

显示特定路由而不是错误页面(404)-Symfony2,symfony,Symfony,我只想显示/sitemap页面,而不是错误页面/404。当然,我不希望重定向,我仍然希望设置404HTTP响应头 这可能吗?我所能看到的就是如何在Twig中设置模板 我绝对不想要重定向。如中所示,您可以通过两种方式覆盖错误页面: 覆盖模板 使用自定义异常控制器 如果您只想在404(HttpNotFoundException)异常上显示/sitemap路由,您可以通过在app/Resources/TwigBundle/views/exception/error404.html.Twig中创建新

我只想显示/sitemap页面,而不是错误页面/404。当然,我不希望重定向,我仍然希望设置404HTTP响应头

这可能吗?我所能看到的就是如何在Twig中设置模板

我绝对不想要重定向。

如中所示,您可以通过两种方式覆盖错误页面:

  • 覆盖模板
  • 使用自定义异常控制器
如果您只想在404(
HttpNotFoundException
)异常上显示
/sitemap
路由,您可以通过在
app/Resources/TwigBundle/views/exception/error404.html.Twig
中创建新模板来覆盖Twig异常模板

烹饪书中没有显示的另一种方法是使用事件侦听器。当内核遇到异常时,将调度一个事件。默认情况下,此异常由Twig提供的异常侦听捕获。您可以选择哪个函数侦听
内核.exception
事件并呈现页面:

<?php
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpFoundation\Response;

public function onKernelException(GetResponseForExceptionEvent $event)
{
    if ($event->getException() instanceof NotFoundHttpException) {
        $response = $this->templating->renderResponse(/* sitemap */);

        $event->setResponse($response)
    }
}

我有一个简单的web应用程序,它由几个Symfony3包组成,所有这些包的控制器都扩展了BaseController。我也有一个包。为了为每个不存在的url显示一个给定页面,我入侵(并简化)了原始的ExceptionController.php(来自TwigBundle):


ps我相信我的代码可以改进,但它工作得很好

最简单的方法是创建此文件:

  • Symfony 3:
    /app/Resources/TwigBundle/views/Exception/error404.html.twig
  • Symfony 4:
    /templates/bundles/TwigBundle/Exception/error404.html.twig
。。。并将此行复制到其中:

{{ render(controller('App\\Controller\\HomepageController::index')) }}
就这样。这将显示带有404状态代码的主页。它只在
prod
环境中工作(清除缓存!),因为在
dev
test
Symfony中总是显示其异常页面

参考资料:


谢谢,我认为事件侦听器是一个不错的选择,但是$this->模板设置无效。我还尝试了$event->templating。我认为通常的控制器方法不可用。我得到了一个未定义的属性:Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent::$templating in…您是正确的,通常的控制器方法不可用,因为它们是服务上方法调用的别名。您应该在服务描述中将
模板化
服务自己注入事件侦听器中。我当时没有意识到这只是设置了一个小树枝模板,而不是实际的页面或控制器。“模板化”服务只显示了一个小树枝模板,而不呈现控制器。当然,它不呈现控制器。这是控制员的工作。但是它应该呈现模板…您可以检查
控制器
类,查看用于在控制器中呈现模板的内容,并将这些服务注入到事件侦听器中。
twig:
    exception_controller: MyappAdminBundle:Exception:show
{{ render(controller('App\\Controller\\HomepageController::index')) }}