Controller in Symfony | Aulab

GUIDE PER ASPIRANTI PROGRAMMATORI

Controller in Symfony

Seguendo la suddivisione proposta dal pattern MVC, possiamo pensare al controller come un blocco logico che ha il compito di reagire agli input ricevuti con un determinato comportamento, avvalendosi eventualmente del supporto del blocco model per l’accesso ai dati, restituendo in output le informazioni utili per la presentazione al blocco view. Formalmente, possiamo dire che…

Lezione 21 / 33
Enza Neri
Immagine di copertina

Vuoi avviare una nuova carriera o fare un upgrade?

Trova il corso Digital & Tech più adatto a te nel nostro catalogo!

Seguendo la suddivisione proposta dal pattern MVC, possiamo pensare al controller come un blocco logico che ha il compito di reagire agli input ricevuti con un determinato comportamento, avvalendosi eventualmente del supporto del blocco model per l’accesso ai dati, restituendo in output le informazioni utili per la presentazione al blocco view.

Formalmente, possiamo dire che un controller è una funzione PHP che riceve le informazioni da un oggetto di tipo Request, esegue una serie di elaborazioni ed infine crea e restituisce un oggetto di tipo Response.

Request e Response sono due classi di Symfony aventi proprietà e metodi pubblici che facilitano l’accesso ai dati della richiesta e la generazione della risposta incapsulando i dati elaborati. Esse appartengono al componente Symfony HttpFoundation che definisce un layer orientato agli oggetti per HTTP. Infatti, nel linguaggio PHP ogni richiesta è gestita all’interno di variabili globali come $_GET, $_POST e $_COOKIE mentre la risposta può essere generata con funzioni come php echo e header().

HttpFoundation sostituisce le variabili globali e le funzioni PHP precedentemente citate da una gerarchia di classi che facilitano la manipolazione e l’elaborazione delle informazioni legate al flusso HTTP.

Nel caso di una web-application, ad esempio, l’utente potrebbe richiedere l’accesso al sistema tramite form di login o l’accesso ad una risorsa specifica come l’articolo di un blog. Solitamente, il controller restituisce una pagina HTML ma è anche possibile restituire un file JSON, XML, un redirect o un errore 404.

In basso, la schematizzazione ad alto livello del meccanismo di richiesta-risposta gestito da un controller:

flusso controller symfony

Come creare un Controller in Symfony

I controller in Symfony sono solitamente dei metodi raggruppati in classi PHP. Ogni gruppo di metodi è legato da una determinata responsabilità, come può essere la gestione di una risorsa quale l’articolo di un blog. In questi casi, parliamo di CRUD (Create, Read, Update e Delete) ovvero di un insieme di metodi che permettono la creazione, lettura, modifica ed eliminazione di un articolo.


La cartella src/controller è il posto in cui devono essere inseriti tutti i file PHP relativi ai controller. La creazione di un classe controller può essere fatta creando manualmente un file, oppure ci si può avvalere del componente MakerBundle di Symfony per la generazione automatica. Per installare MakerBundle è sufficiente lanciare da terminale il seguente comando:

composer require --dev symfony/maker-bundle

Come già visto in precedenza, Symfony Flex si occuperà di installare il bundle e di configurarlo al posto nostro.

Per generare un controller utilizzare il comando:

php bin/console make:controller

creazione controller symfony

La console ci chiederà il nome da assegnare al nuovo controller. Il suffisso Controller viene aggiunto in automatico dal comando nel caso in cui non venisse inserito dall’utente. Questa è una convenzione utilizzata da Symfony per far riconoscere allo sviluppatore in maniera semplice e veloce il tipo di file direttamente dal nome. Come si nota dall’output della console, oltre alla creazione del controller, il comando si è occupato anche di creare una cartella hello sotto templates generando all’interno il file Twig index.html.twig. Questo è avvenuto perchè sul progetto è già installato il modulo twig. In caso contrario, verrebbe generato soltanto il file relativo al controller.

Analizziamo il codice del Controller appena generato:

<?php


namespace App\Controller;


use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;


class HelloController extends AbstractController
{
    #[Route('/hello', name: 'app_hello')]
    public function index(): Response
    {
        return $this->render('hello/index.html.twig', [
            'controller_name' => 'HelloController',
        ]);
    }
}

Il Controller ha la struttura di un classico file PHP con all’inizio il tag di apertura <?php. Successivamente è presente il namespace della classe. Notiamo che il namespace è App. In generale, tutto il codice presente sotto la cartella src del progetto fa riferimento ad App. Questa configurazione è stata effettuata in automatico durante l’installazione ed è possibile visualizzarla all’interno del file composer.json, come mostrato dallo snippet seguente:

  "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    },

HelloController estende la classe AbstractController di Symfony dalla quale eredita una serie di metodi utili per le operazioni che vengono eseguite comunemente nei controller come il rendering delle view, l’accesso ai service e la generazione delle risposte.

L’unica funzione contenuta all’interno della classe HelloController è index(). Tale funzione si occupa di effettuare il render della view hello/index.html.twig. Sopra alla definizione della funzione è presente la route ovvero il path della richiesta sul quale si attiverà il controller creato.

Per verificare che l’associazione tra path e controller sia stata registrata in Symfony è possibile utilizzare un utile comando della console:

php bin/console debug:router

L’output del comando contiene l’elenco delle route presenti nel progetto.

output console route

Nel nostro caso, notiamo come al percorso /hello sia associato app_hello che fa riferimento al metodo index() definito all’interno della classe HelloController. Aprendo in un browser l’indirizzo symfony-test.local/hello avremo in output la seguente schermata.

controller in symfony 4

Ora proviamo a riadattare lo schema relativo al flusso di Symfony, analizzato poc’anzi, alla richiesta che ci ha portati a visualizzare la pagina di “Hello” appena creata

flusso controller in symfony

Come si nota, Symfony, una volta intercettata la Request, ricerca il controller associato al path /hello, ovvero HelloController->index(), ed elabora la pagina HTML tramite il template /hello/index.html.twig da restituire come Response. Rispetto allo schema completo, in questo flusso, non è presente il blocco “Model”, concetto che approfondiremo più avanti.

Gestione degli errori in Symfony

I controller, come detto in precedenza, possono restituire risposte di svariato tipo.
Durante l’elaborazione di una richiesta, può capitare di dover gestire delle eccezioni legate a problematiche come risorsa non trovata (404) o errore generico del server (500).

Modifichiamo il codice della classe controller HelloController aggiungendo una nuova function che, a scopo dimostrativo, genera un’eccezione di tipo NotFoundHTTPException.

 #[Route('/hello-404', name: 'app_hello_404')]
    public function notFound(): Response
    {
        throw $this->createNotFoundException('Ops! Risorsa non trovata');
    }

Accedendo tramite browser all’indirizzo symfony-test.local/hello-404 vedremo la pagina di errore:

error 404 symfony

In Symfony, tutti gli errori sono trattati come eccezioni, siano essi 404 o errori fatali. In ambiente di sviluppo, Symfony, per aiutarci a scovare il problema che ha generato l’eccezione, genera una pagina speciale (come quella precedente) in cui sono presenti molte informazioni utili per il debug. Questa pagina contiene una serie di informazioni sensibili riguardo il sistema e il progetto e può essere utilizzata da utenti malevoli per scoprire exploit e danneggiare il sito. In ambiente di produzione, infatti, Symfony sostituisce tale pagina con una minimale di errore generico che può essere personalizzata a proprio piacimento.

Sei indeciso sul percorso? 💭

Parliamone! Scrivici su Whatsapp e risponderemo a tutte le tue domande per capire quale dei nostri corsi è il più adatto alle tue esigenze.

Oppure chiamaci al 800 128 626