2013-04-13 8 views

risposta

17

Come mostrato nella the Symfony Cookbook è possibile ignorare le pagine di errore in due modi:

  • override i modelli
  • Utilizzando un controller eccezione personalizzata

Se solo si desidera visualizzare il percorso /sitemap su a 404 (HttpNotFoundException) eccezione è possibile sovrascrivere il modello di eccezione Twig creando un nuovo modello in app/Resources/TwigBundle/views/Exception/error404.html.twig.

Un altro modo non mostrato nel ricettario è l'utilizzo di un listener di eventi. Quando il kernel incontra un'eccezione, viene inviato un evento kernel.exception. Per impostazione predefinita, questa eccezione viene catturata dall'eccezione di ascolto fornita da Twig. È possibile create your own event listener che intercetta l'evento kernel.exception e rende una pagina:

<?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) 
    } 
} 

(non ho ancora testato questo codice, così si dovrebbe provare voi stessi e si deve iniettare il servizio di template nel listener di eventi da soli! , ovviamente).

+0

Grazie, l'ascoltatore di eventi è la strada da percorrere, penso, ma $ this-> templating non è valido. Ho anche provato $ event-> templating. Non penso che i metodi di controllo usuali siano disponibili. Ottengo una proprietà Undefined: Symfony \ Component \ HttpKernel \ Event \ GetResponseForExceptionEvent :: $ templating in ... – user2143356

+0

Sei corretto, i soliti metodi di controllo non sono disponibili in quanto sono alias per le chiamate di metodo sui servizi. Dovresti inserire il servizio 'templating' nel listener degli eventi nella descrizione del servizio. –

+0

Non ero realista al momento in cui questo imposta solo un modello Twig, non una pagina o un controller. – user2143356

0

Ho una semplice applicazione Web composta da diversi bundle Symfony3, i cui controller estendono un BaseController. Ho anche un AdminBundle. Per visualizzare una determinata pagina per ogni url non inesistente, ho inciso (e resa più semplice) l'originale ExceptionController.php (dal 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(); 
    } 
} 

ho definire il mio modello di errore come mi piaceva.

ho bisogno di aggiungere la seguente riga all'interno config.yml

twig: 
    exception_controller: MyappAdminBundle:Exception:show 

ps Sono sicuro che il mio codice può essere migliorato, ma funziona bene.

Problemi correlati