2013-04-13 102 views

回答

17

the Symfony Cookbook所示,你可以覆蓋兩個方面的錯誤頁面:

  • 重寫模板
  • 使用自定義異常控制器

如果你只是想顯示在/sitemap路線404(HttpNotFoundException)例外,您可以通過在app/Resources/TwigBundle/views/Exception/error404.html.twig中創建新模板來覆蓋Twig例外模板。

食譜中未顯示的另一種方法是使用事件偵聽器。當內核遇到異常時,將調度一個kernel.exception事件。默認情況下,此異常由Twig提供的異常偵聽捕獲。您可以create your own event listener它偵聽kernel.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) 
    } 
} 

(我還沒有測試此代碼,所以你應該自己嘗試它,你必須注入模板服務到事件監聽器自己! , 當然)。

+0

謝謝,事件監聽器是我想要的方式,但$ this-> templating無效。我也試過$ event->模板。我不認爲通常的控制器方法可用。我得到一個未定義的屬性:Symfony \ Component \ HttpKernel \ Event \ GetResponseForExceptionEvent :: $ templating in ... – user2143356

+0

你是對的,通常的控制器方法不可用,因爲那些是服務上方法調用的別名。您應該在服務描述中自己將'templating'服務注入到事件監聽器中。 –

+0

我當時沒有寫實主義,只是設置了一個小枝模板,而不是一個實際的頁面或控制器。 – user2143356

0

我有一個簡單的Web應用程序組成的幾個Symfony3包,其所有的控制器擴展一個BaseController。我也有一個AdminBundle。要顯示給定頁面的每一個不存在的網址,我砍死(和更簡單)原ExceptionController.php(從TwigBundle):

<?php 

namespace MyApp\AdminBundle\Controller; 

use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Symfony\Component\HttpFoundation\Response; 
use Symfony\Component\HttpFoundation\Request; 

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; 
use MyApp\Controller\BaseController; 

use Symfony\Component\Debug\Exception\FlattenException; 
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; 

class ExceptionController extends BaseController 
{ 
    /** 
    * Converts an Exception to a Response. 
    * 
    * @param Request    $request The request 
    * @param FlattenException  $exception A FlattenException instance 
    * @param DebugLoggerInterface $logger A DebugLoggerInterface instance 
    * 
    * @return Response 
    * @throws \InvalidArgumentException When the exception template does not exist 
    */ 
    public function showAction(Request $request, FlattenException $exception, DebugLoggerInterface $logger = null) 
    { 
     $currentContent = $this->getAndCleanOutputBuffering($request->headers->get('X-Php-Ob-Level', -1)); 
     $code = $exception->getStatusCode(); 
     return $this->render('MyappAdminBundle:Admin:error.html.twig', 
      array(
       'status_code' => $code, 
       'status_text' => isset(Response::$statusTexts[$code]) ? Response::$statusTexts[$code] : '', 
       'exception' => $exception, 
       'logger' => $logger, 
       'currentContent' => $currentContent, 
      ) 
     ); 
    } 

    /** 
    * @param int $startObLevel 
    * 
    * @return string 
    */ 
    protected function getAndCleanOutputBuffering($startObLevel) 
    { 
     if (ob_get_level() <= $startObLevel) { 
      return ''; 
     } 

     Response::closeOutputBuffers($startObLevel + 1, true); 

     return ob_get_clean(); 
    } 
} 

我定義我的錯誤模板,我很喜歡。

我需要添加config.yml內以下行

twig: 
    exception_controller: MyappAdminBundle:Exception:show 

PS我相信我的代碼可以改善,但它工作正常。

相關問題