Routing in Symfony | Aulab

GUIDE PER ASPIRANTI PROGRAMMATORI

Routing in Symfony

Il routing è uno degli aspetti fondamentali di qualsiasi web framework moderno in quanto permette di mappare URI specifici a determinate azioni all’interno dell’applicazione. In sostanza, il routing determina come l’applicazione risponde ad ogni singola richiesta HTTP. Grazie alla configurazione del routing in Symfony, quando l’applicazione riceve una richiesta è in grado di invocare il…

Lezione 22 / 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!

Il routing è uno degli aspetti fondamentali di qualsiasi web framework moderno in quanto permette di mappare URI specifici a determinate azioni all’interno dell’applicazione. In sostanza, il routing determina come l’applicazione risponde ad ogni singola richiesta HTTP.

Grazie alla configurazione del routing in Symfony, quando l’applicazione riceve una richiesta è in grado di invocare il metodo corretto di una determinata classe controller per generare una risposta.

Come configurare il routing in Simfony

Le rotte possono essere configurate in vari formati, ovvero YAML, XML, PHP o tramite PHP Attributes. Tutti questi formati sono intercambiabili tra di loro in quanto offrono le stesse funzionalità e le stesse performance. Le best practices di Symfony consigliano di utilizzare gli attributes in quanto, come già visto nel controller HelloController, sono definite assieme alla funzione controller, nello stesso file, evitando così di dover gestire più file in formati e cartelle differenti.

Di seguito, una overview sulla configurazione delle route nei vari formati possibili. Successivamente, ci concentreremo solo sull’utilizzo dei PHP Attributes.

Configurare una route con PHP Attributes

Gli attributes in PHP sono una caratteristica introdotta con PHP 8.0. Essi forniscono un modo per aggiungere meta-dati a classi, metodi, proprietà e parametri, simili a quelle che vengono chiamate annotations in altri linguaggi di programmazione. Nel caso delle route, prendiamo l’esempio del nostro HelloController in cui abbiamo definito il path /hello

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

Questa configurazione definisce una route chiamata app_hello che mappa l’URI /hello al metodo index() della classe HelloController.

Configurare una route con YAML

La stessa route può essere configurata tramite YAML. Per farlo, è necessario creare un file nella cartella config chiamato routes.yaml.

# config/routes.yaml
app_hello:
    path: /hello
    controller: App\Controller\HelloController::index

Configurare una route con XML 

Utilizzando il formato XML, la route può essere configurata nel seguente modo:

<!-- config/routes.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/routing
        https://symfony.com/schema/routing/routing-1.0.xsd">

    <route id="app_hello" path="/hello"
           controller="App\Controller\HelloController::index"/>

</routes>

Nb. Il file routes.xml deve essere creato in config.

Configurare una route con PHP

Per configurare le route tramite PHP è necessario creare il file routes.php nella directory config:

// config/routes.php
use App\Controller\HelloController;
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;

return function (RoutingConfigurator $routes): void {
    $routes->add('app_hello', '/hello)
        ->controller([HelloController::class, 'index'])
    ;
};

Specializzare le route con le opzioni methods e condition

La route app_hello precedentemente definita non specifica alcun metodo HTTP. In questa casistica, Symfony permette di contattare tale route con qualsiasi metodo come GET e POST. Utilizzando l’opzione methods è possibile limitare l’accesso alla route ad uno o più metodi HTTP.

Supponiamo di voler abilitare la route /hello solo per le chiamate GET e HEAD. Il codice verrà modificato nel seguento modo:

#[Route('/hello', name: 'app_hello', methods: ['GET', 'HEAD'])]

Un’altra opzione che è possibile utilizzare nella configurazione delle route è condition. Essa permette di abilitare la route solo quando si verificano determinate condizioni logiche. La sintassi delle espressioni deve seguire quella del componente ExpressionLanguage di Symfony.

Supponiamo, ad esempio, di voler attivare il path /hello solo per le chiamate GET e che contengono nell’header della richiesta un attributo chiamato “APPLICATION-KEY”:

#[Route(
        '/hello,
        name: 'app_hello',
        condition: "context.getMethod() == 'GET' and request.headers.has('APPLICATION-KEY')"
    )]

Parametri delle route in Symfony

Fino a questo momento, abbiamo visto come associare un path statico ad una route. Spesso, però, si ha la necessità di ricevere in input dei valori da parte del client per poter eseguire delle elaborazioni specifiche. Ad esempio, in un blog, per accedere al contenuto di articolo potremmo pensare di creare una route /articolo. Tale route è uguale per ogni articolo. Per specificare a quale articolo si è interessati, è necessario introdurre il concetto di parametri dinamici delle route.

Infatti, un parametro dinamico è un valore variabile che può essere fornito ad una route.

In Symfony, ad una route possono essere associati uno o più parametri. Per farlo, è sufficiente usare la seguente sintassi:

/path/{nome del parametro}

Nel caso dell’articolo di un blog, la definizione della route potrebbe essere la seguente:

/articolo/{id}

{id} è il parametro dinamico che rappresenta l’id di un articolo. Quando un utente visita, ad esempio, l’URL /articolo/43, il valore 43 viene fornito al controller all’interno della variabile id. In questo modo, il controller può richiedere al database l’articolo tramite il suo identificativo univoco.

Esempio di una route con parametro

A scopo dimostrativo, creiamo un nuovo metodo all’interno della solita classe HelloController:

  #[Route('/hello/random/{max}', name: 'app_hello_random')]
    public function randomNumber(int $max): Response
    {
        $number = random_int(0, $max);
        return new Response("Numero casuale: $number");
    }

La route sopra definita /hello/random/{max} prevede un parametro dinamico chiamato max. Il metodo controller randomNumber associato alla route genera e fornisce in output un numero casuale che va da 0 fino al valore del parametro ricevuto in input. Accedendo alla URL symfony-test.local/hello/random/100 otterremo un numero casuale tra 0 e 100:

routing in symfony

La funzione randomNumber ha utilizzato correttamente il parametro ricevuto. Se, però, al posto di un parametro numerico, inseriamo un valore di tipo stringa, otteniamo la seguente schermata:

routing in symfony

Symfony ha risposto con un errore del server (500 Internal Server Error) perchè randomNumber ha specificato nella firma del metodo un parametro id di tipo int, mentre noi abbiamo fornito un valore testuale.

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