Skip to content
  • About
    • What is Symfony?
    • Community
    • News
    • Contributing
    • Support
  • Documentation
    • Symfony Docs
    • Symfony Book
    • Screencasts
    • Symfony Bundles
    • Symfony Cloud
    • Training
  • Services
    • Platform.sh for Symfony Best platform to deploy Symfony apps
    • SymfonyInsight Automatic quality checks for your apps
    • Symfony Certification Prove your knowledge and boost your career
    • SensioLabs Professional services to help you with Symfony
    • Blackfire Profile and monitor performance of your apps
  • Other
  • Blog
  • Download
sponsored by
  1. Home
  2. Documentation
  3. Symfony: The Fast Track
  4. Italian
  5. La creazione di un controller

La creazione di un controller

Il nostro progetto del guestbook è già attivo sui server di produzione, ma abbiamo imbrogliato un po'. Il progetto non ha ancora nessuna pagina. L'homepage risulta essere una noiosa pagina di errore 404. Sistemiamo le cose.

Quando arriva una richiesta HTTP come per la homepage (http://localhost:8000/), Symfony cerca di trovare una rotta che corrisponda al percorso della richiesta (/ in questo caso). Una rotta è il collegamento tra il percorso della richiesta e una funzione callable di PHP che crea la risposta HTTP per quella richiesta.

Queste funzioni "callable" sono chiamate "controller". In Symfony, la maggior parte dei controller è implementata come classe PHP. Possiamo creare una classe di questo tipo in modo manuale ma, siccome ci piace andare veloci, vediamo come Symfony ci può aiutare.

Essere pigri con MakerBundle

Per generare dei controller senza sforzo, possiamo usare il pacchetto symfony/maker-bundle, il quale è stato installato come parte del pacchetto webapp.

MakerBundle ci aiuta a generare un sacco di classi diverse. Lo useremo molto spesso in questo libro. Ogni "generatore" è definito in un comando e tutti i comandi fanno parte del namespace dei comandi make.

Il comando list della console di Symfony elenca tutti i comandi disponibili sotto un dato namespace; possiamo usarlo per scoprire tutti i generatori forniti da MakerBundle:

1
$ symfony console list make

Scegliere un formato per la configurazione

Prima di creare il primo controller del progetto, dobbiamo decidere quali formati di configurazione vogliamo utilizzare. Symfony supporta nativamente YAML, XML, PHP e `Attributi PHP`.

Per la configurazione relativa ai pacchetti, YAML è la scelta migliore. Questo è il formato utilizzato per la cartella config/. Spesso, quando si installa un nuovo pacchetto, la ricetta del pacchetto stesso aggiungerà un nuovo file con estensione .yaml a questa cartella.

Per la configurazione relativa al codice PHP, gli attributi sono una scelta migliore poiché sono definite nel codice stesso. Prendiamo in esame questo esempio: quando una richiesta arriva all'applicazione, la configurazione deve dire a Symfony quale specifico controller (una classe PHP) dovrà gestirla. Se utilizzassimo un formato di configurazione tra YAML, XML e PHP, due file sarebbero coinvolti (il file di configurazione e il file del controller PHP). Utilizzando gli attributi, la configurazione sarà inclusa direttamente nella classe del controller.

Come fare a sapere il nome del pacchetto che ci serve installare per una determinata funzionalità? Il più delle volte non c'è bisogno di saperlo, infatti Symfony ci dirà il nome del pacchetto da installare attraverso dei messaggi d'errore. Lanciare il comando symfony console make:message senza aver installato il pacchetto messenger, per esempio, avrebbe sollevato un'eccezione contenente un suggerimento riguardo a cosa installare.

Generare un controller

Creiamo il nostro primo controller tramite il comando make:controller:

1
$ symfony console make:controller ConferenceController

Il comando crea una classe ConferenceController nella cartella src/Controller/. La classe generata sarà composta da codice predefinito e pronto per essere messo a punto:

src/Controller/ConferenceController.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
namespace App\Controller;

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

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

L'attributo #[Route('/conference', name: 'app_conference')] è ciò che rende il metodo index() un controller (la configurazione è assieme al codice che configura).

Quando si visita /conference nel browser, il controller viene eseguito e una risposta viene restituita.

Modifichiamo la rotta per farla corrispondere alla homepage:

1
2
3
4
5
6
7
8
9
10
11
--- a/src/Controller/ConferenceController.php
+++ b/src/Controller/ConferenceController.php
@@ -8,7 +8,7 @@ use Symfony\Component\Routing\Attribute\Route;

 class ConferenceController extends AbstractController
 {
-    #[Route('/conference', name: 'app_conference')]
+    #[Route('/', name: 'homepage')]
     public function index(): Response
     {
         return $this->render('conference/index.html.twig', [

Il parametro name della rotta sarà utile qualora volessimo fare riferimento alla homepage all'interno del codice. Invece di scrivere direttamente il percorso / potremo utilizzare il nome della rotta.

Al posto della pagina predefinita, restituiamo una semplice pagina HTML:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
--- a/src/Controller/ConferenceController.php
+++ b/src/Controller/ConferenceController.php
@@ -11,8 +11,13 @@ class ConferenceController extends AbstractController
     #[Route('/', name: 'homepage')]
     public function index(): Response
     {
-        return $this->render('conference/index.html.twig', [
-            'controller_name' => 'ConferenceController',
-        ]);
+        return new Response(<<<EOF
+            <html>
+                <body>
+                    <img src="/images/under-construction.gif" />
+                </body>
+            </html>
+            EOF
+        );
     }
 }

Aggiorniamo il browser:

/

La responsabilità principale di un controller è quella di restituire una Response HTTP per la richiesta.

Siccome la rimanente parte del capitolo riguarda codice che non vorremo memorizzare, facciamo commit dei cambiamenti ora:

1
2
$ git add .
$ git commit -m'Add the index controller'

Aggiunta di un "easter egg"

Per dimostrare come una risposta possa sfruttare le informazioni provenienti dalla richiesta, aggiungiamo un piccolo easter egg (contenuto nascosto). Ogni volta che la homepage contiene una query string come ?hello=Fabien, aggiungiamo del testo per salutare la persona:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
--- a/src/Controller/ConferenceController.php
+++ b/src/Controller/ConferenceController.php
@@ -3,17 +3,24 @@
 namespace App\Controller;

 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\Routing\Attribute\Route;

 class ConferenceController extends AbstractController
 {
     #[Route('/', name: 'homepage')]
-    public function index(): Response
+    public function index(Request $request): Response
     {
+        $greet = '';
+        if ($name = $request->query->get('hello')) {
+            $greet = sprintf('<h1>Hello %s!</h1>', htmlspecialchars($name));
+        }
+
         return new Response(<<<EOF
             <html>
                 <body>
+                    $greet
                     <img src="/images/under-construction.gif" />
                 </body>
             </html>

Symfony espone i dati della richiesta attraverso un oggetto Request. Quando Symfony rileva un parametro del controller con questo tipo, passa automaticamente la richiesta attraverso questo oggetto: possiamo utilizzarlo per ottenere l'elemento name dalla query string e aggiungere un <h1> al titolo della pagina.

Proviamo a visitare in un browser il percorso / e poi /?hello=Fabien per vedere la differenza.

Note

Nota: la chiamata a htmlspecialchars() serve per evitare problemi di XSS (cross-site scripting). Questa cosa sarà fatta in modo automatico quando utilizzeremo un sistema appropriato per i template.

Avremmo anche potuto rendere il nome parte dell'URL:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
--- a/src/Controller/ConferenceController.php
+++ b/src/Controller/ConferenceController.php
@@ -9,11 +9,11 @@ use Symfony\Component\Routing\Attribute\Route;

 class ConferenceController extends AbstractController
 {
-    #[Route('/', name: 'homepage')]
-    public function index(Request $request): Response
+    #[Route('/hello/{name}', name: 'homepage')]
+    public function index(string $name = ''): Response
     {
         $greet = '';
-        if ($name = $request->query->get('hello')) {
+        if ($name) {
             $greet = sprintf('<h1>Hello %s!</h1>', htmlspecialchars($name));
         }

La parte {name} della rotta è un parametro di rotta dinamico: funziona come segnaposto. Possiamo dunque visitare /hello e poi /hello/Fabien attraverso il browser per ottenere lo stesso risultato di prima. Possiamo inoltre ottenere il valore del parametro {{name}} aggiungendo una variabile al controller con lo stesso nome (quindi, $name).

Annulliamo le modifiche che abbiamo appena fatto:

1
$ git checkout src/Controller/ConferenceController.php
1
2
$ git reset HEAD src/Controller/ConferenceController.php
$ git checkout src/Controller/ConferenceController.php

Variabili di debug

La funzione dump() di Symfony è un ottimo aiuto per il debug. È sempre disponibile e ci consente di eseguire il dump di variabili complesse in una forma bella e interattiva.

Cambiamo momentaneamente il file src/Controller/ConferenceController.php per eseguire il dump dell'oggetto Request:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
--- a/src/Controller/ConferenceController.php
+++ b/src/Controller/ConferenceController.php
@@ -3,14 +3,17 @@
 namespace App\Controller;

 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\Routing\Attribute\Route;

 class ConferenceController extends AbstractController
 {
     #[Route('/', name: 'homepage')]
-    public function index(): Response
+    public function index(Request $request): Response
     {
+        dump($request);
+
         return new Response(<<<EOF
             <html>
                 <body>

Quando ricarichiamo la pagina sarà possibile notare la nuova icona "target" nella barra degli strumenti; ci consentirà di inspezionare il dump. È possibile cliccare su di essa per accedere a una pagina dove la navigazione sarà più semplice:

/

Annulliamo le modifiche che abbiamo appena fatto:

1
$ git checkout src/Controller/ConferenceController.php
1
2
$ git reset HEAD src/Controller/ConferenceController.php
$ git checkout src/Controller/ConferenceController.php

Andare oltre

  • Il sistema di rotte di Symfony;
  • Tutorial su rotte, controller e pagine in SymfonyCasts;
  • Attributi PHP:
  • Il componente HttpFoundation;
  • Attacchi di sicurezza XSS (Cross-Site Scripting);
  • Il Cheat Sheet del componente delle rotte di Symfony.
Previous page Risoluzione dei problemi
Next page Impostare il database
This work, including the code samples, is licensed under a Creative Commons BY-NC-SA 4.0 license.
TOC
    Version

    Symfony 6.4 is backed by

    Get your Sylius expertise recognized

    Get your Sylius expertise recognized

    Be safe against critical risks to your projects and businesses

    Be safe against critical risks to your projects and businesses

    Version:
    Locale:
    ebook

    This book is backed by:

    see all backers

    Symfony footer

    Avatar of zenmate, a Symfony contributor

    Thanks zenmate for being a Symfony contributor

    2 commits • 186 lines changed

    View all contributors that help us make Symfony

    Become a Symfony contributor

    Be an active part of the community and contribute ideas, code and bug fixes. Both experts and newcomers are welcome.

    Learn how to contribute

    Symfony™ is a trademark of Symfony SAS. All rights reserved.

    • What is Symfony?

      • What is Symfony?
      • Symfony at a Glance
      • Symfony Components
      • Symfony Releases
      • Security Policy
      • Logo & Screenshots
      • Trademark & Licenses
      • symfony1 Legacy
    • Learn Symfony

      • Symfony Docs
      • Symfony Book
      • Reference
      • Bundles
      • Best Practices
      • Training
      • eLearning Platform
      • Certification
    • Screencasts

      • Learn Symfony
      • Learn PHP
      • Learn JavaScript
      • Learn Drupal
      • Learn RESTful APIs
    • Community

      • Symfony Community
      • SymfonyConnect
      • Events & Meetups
      • Projects using Symfony
      • Contributors
      • Symfony Jobs
      • Backers
      • Code of Conduct
      • Downloads Stats
      • Support
    • Blog

      • All Blog Posts
      • A Week of Symfony
      • Case Studies
      • Cloud
      • Community
      • Conferences
      • Diversity
      • Living on the edge
      • Releases
      • Security Advisories
      • Symfony Insight
      • Twig
      • SensioLabs Blog
    • Services

      • SensioLabs services
      • Train developers
      • Manage your project quality
      • Improve your project performance
      • Host Symfony projects

      Powered by

    Follow Symfony