Per iniziare a scrivere un po' di codice del nostro progetto abbiamo bisogno di introdurre dei concetti che provengono dal pattern MVC (Model-View-Controller) e che ci seguiranno durante lo sviluppo.
- La Rotta è un indirizzo che viene chiamato dal browser (o da un qualsiasi altro client) attraverso una richiesta HTTP.
- Il Controller contiene il codice che viene eseguito quando viene richiamata una specifica rotta nel progetto.
- La Vista contiene il risultato che verrà restituito al client dopo che il controller ha completato le sue operazioni.
Rotte in Symfony
In Symfony le rotte possono essere definite in due diversi modi: attraverso file di configurazione (YAML, XML o PHP) o con delle annotation all'interno del controller.
Nel file app/config/routes.yaml
possiamo definire le nostre rotte come nell'esempio seguente:
user_profile:
path: /profile
controller: Kvak\Controller\ProfileController::profile
methods: GET|HEAD
Con queste 4 righe di configurazione stiamo dicendo a Symfony che deve intercettare la rotta all'indirizzo http://<indirizzo_applicazione>/profile
per i metodi GET e HEAD e che deve eseguire il codice contenuto nel metodo profile()
del controller ProfileController
.
Nel progetto utilizzeremo dei file di configurazione YAML ma per completezza vediamo anche un esempio con le annotation.
<?php
namespace Kvak\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
class ProfileController extends AbstractController
{
/**
* @Route("/profile", name="user_profile", methods={"GET","HEAD"})
*/
public function profile()
{
// ..
}
}
Con un semplice commento in cima alla definizione di un controller abbiamo creato una rotta che risponderà all'indirizzo http://<indirizzo_applicazione>/profile
.
Controller
In Symfony un controller è una funzione PHP che legge informazioni da una richiesta HTTP, le elabora e restituisce una risposta al client. Un controller può essere una qualsiasi funzione PHP callable ma nella maggior parte dei casi è costituito da un metodo all'interno di una classe.
Vediamo un esempio:
<?php
namespace Kvak\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class ProfileController extends AbstractController
{
public function profile(Request $request): Response
{
return new Response("<html><head></head><body>Hello world!</body></html>");
}
}
Symfony inietta automaticamente un oggetto Request
come parametro del nostro controller. Questo oggetto contiene al suo interno tutte le informazioni che ci ha inviato il client: parametri in GET e/o in POST, gli header, i cookie, ecc.
Ogni controller deve poi necessariamente restituire un oggetto di tipo Response
che conterrà invece il body della risposta, header e cookie.
Vista
Le modalità con cui viene gestita una vista dipendono da diversi fattori: ad esempio se stiamo restituendo delle pagine in HTML o se stiamo lavorando a delle API che quindi restituiranno solo JSON (o XML o qualsiasi altro formato di interscambio).
Quando si lavora a delle API che restituiscono del semplice JSON gestire la vista è molto semplice. È sufficiente far restituire a Symfony una response di tipo Symfony\Component\HttpFoundation\JsonResponse
che accetta come primo parametro i dati da mostrare. La classe JsonResponse
, inoltre, verifica se i dati da mostrare sono in un oggetto che estende l’interfaccia JsonSerializable
; in tal caso richiamerà automaticamente il metodo jsonSerialize()
senza la necessità di effettuare manualmente la conversione.
Lavorando con pagine HTML abbiamo sicuramente necessità diverse perché dovremo gestire non solo template HTML ma anche immagini, CSS e altri asset statici. Per adesso concentriamoci solo sui file HTML rimandando ad altre lezioni anche la gestione degli assets.
Symfony Framework integra un template engine semplice da usare: Twig. Grazie ad esso possiamo gestire agevolmente le viste delle nostre pagine HTML. Vediamo un semplice esempio rimandando gli approfondimenti alle prossime lezioni:
class ProfileController extends AbstractController
{
public function profile(Request $request): Response
{
$user = ['name' => 'Simone'];
return $this->render('user/profile.html.twig', ['user' => $user]);
}
}
templates/user/profile.html.twig
<html>
<head>
<title>Ciao {user.name}</title>
</head>
<body>
<p>Benvenuto {user.name} sul tuo profilo.</p>
</body>
</html>