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. Ascolto degli eventi

Ascolto degli eventi

Al layout attuale manca una barra di navigazione per tornare alla homepage o per passare da una conferenza all'altra.

Aggiungere una barra di navigazione

Tutto ciò che va visualizzato su ogni pagina, come una barra di navigazione, dovrebbe far parte del layout di base:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
--- a/templates/base.html.twig
+++ b/templates/base.html.twig
@@ -12,6 +12,15 @@
         {% endblock %}
     </head>
     <body>
+        <header>
+            <h1><a href="{{ path('homepage') }}">Guestbook</a></h1>
+            <ul>
+            {% for conference in conferences %}
+                <li><a href="{{ path('conference', { id: conference.id }) }}">{{ conference }}</a></li>
+            {% endfor %}
+            </ul>
+            <hr />
+        </header>
         {% block body %}{% endblock %}
     </body>
 </html>

Aggiungere questo codice al layout significa richiedere che tutti i template che lo estendono debbano definire una variabile conferences, che deve essere creata e passata dai controller.

Avendo solo due controller, si potrebbe fare come segue (non applicare la modifica, perché vedremo presto un'alternativa migliore):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
--- a/src/Controller/ConferenceController.php
+++ b/src/Controller/ConferenceController.php
@@ -21,12 +21,13 @@ class ConferenceController extends AbstractController
     }

     #[Route('/conference/{id}', name: 'conference')]
-    public function show(Request $request, Conference $conference, CommentRepository $commentRepository): Response
+    public function show(Request $request, Conference $conference, CommentRepository $commentRepository, ConferenceRepository $conferenceRepository): Response
     {
         $offset = max(0, $request->query->getInt('offset', 0));
         $paginator = $commentRepository->getCommentPaginator($conference, $offset);

         return $this->render('conference/show.html.twig', [
+            'conferences' => $conferenceRepository->findAll(),
             'conference' => $conference,
             'comments' => $paginator,
             'previous' => $offset - CommentRepository::COMMENTS_PER_PAGE,

Immaginiamo di dover aggiornare decine di controller e fare lo stesso con tutti quelli nuovi. Non è molto pratico. Deve esserci un modo migliore.

Twig ha il concetto di variabili globali. Una variabile globale è disponibile in tutti i template. È possibile definirla in un file di configurazione, ma funziona solo per i valori statici. Per aggiungere tutte le conferenze come variabile globale di Twig, creeremo un listener.

Scoprire gli eventi di Symfony

Symfony è dotato di un componente EventDispatcher, che si occupa in determinati momenti di inviare eventi, i quali possono essere ascoltati da listener. I listener si agganciano alle parti interne del framework.

Per esempio, alcuni eventi permettono di interagire con il ciclo di vita delle richieste HTTP. Durante la gestione di una richiesta, il dispatcher invia eventi quando una richiesta è stata creata, quando un controller sta per essere eseguito, quando una risposta è pronta per essere inviata o quando è stata sollevata un'eccezione. Un listener può ascoltare uno o più eventi ed eseguire una logica basata sull'evento.

Gli eventi sono punti d'estensione ben definiti che rendono il framework più generico ed estensibile. Molti componenti di Symfony come Security, Messenger, Workflow o Mailer li usano ampiamente.

Un altro esempio di eventi e listener in azione è nel ciclo di vita di un comando: è possibile creare un listener per eseguire del codice prima dell'esecuzione di qualsiasi comando.

Qualsiasi pacchetto o bundle può anche inviare i propri eventi per rendere il codice estensibile.

Per evitare di avere un file di configurazione che descriva quali eventi un listener vuole ascoltare, creare un subscriber. Un subscriber è un listener con un metodo statico getSubscribedEvents() che restituisce la sua configurazione. Questo permette ai subscriber di registrarsi automaticamente nel dispatcher di Symfony.

Implementare un Subscriber

Ormai conoscete la canzone a memoria, usate MakerBundle per generare un subscriber:

1
$ symfony console make:subscriber TwigEventSubscriber

Il comando chiederà quale evento si vuole ascoltare. Scegliere l'evento Symfony\Component\HttpKernel\Event\ControllerEvent, che viene inviato appena prima che il controller venga chiamato. È il momento migliore per iniettare la variabile globale conferences, in modo che Twig vi abbia accesso quando il controller processerà il template. Aggiorniamo il subscriber come segue:

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
29
--- a/src/EventSubscriber/TwigEventSubscriber.php
+++ b/src/EventSubscriber/TwigEventSubscriber.php
@@ -2,14 +2,25 @@

 namespace App\EventSubscriber;

+use App\Repository\ConferenceRepository;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 use Symfony\Component\HttpKernel\Event\ControllerEvent;
+use Twig\Environment;

 class TwigEventSubscriber implements EventSubscriberInterface
 {
+    private $twig;
+    private $conferenceRepository;
+
+    public function __construct(Environment $twig, ConferenceRepository $conferenceRepository)
+    {
+        $this->twig = $twig;
+        $this->conferenceRepository = $conferenceRepository;
+    }
+
     public function onControllerEvent(ControllerEvent $event): void
     {
-        // ...
+        $this->twig->addGlobal('conferences', $this->conferenceRepository->findAll());
     }

     public static function getSubscribedEvents(): array

Ora, è possibile aggiungere tutti i controller che si desidera: la variabile conferences sarà sempre disponibile nei Twig.

Note

Parleremo di un'alternativa molto migliore dal punto di vista delle prestazioni in uno dei prossimi passi.

Ordinamento delle conferenze per anno e città

Ordinare l'elenco delle conferenze per anno può facilitare la navigazione. Potremmo creare un metodo personalizzato per recuperare e ordinare tutte le conferenze. Optiamo invece per ridefinire l'implementazione predefinita del metodo findAll(), per assicurarci che l'ordinamento si applichi ovunque:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
--- a/src/Repository/ConferenceRepository.php
+++ b/src/Repository/ConferenceRepository.php
@@ -21,6 +21,11 @@ class ConferenceRepository extends ServiceEntityRepository
         parent::__construct($registry, Conference::class);
     }

+    public function findAll(): array
+    {
+        return $this->findBy([], ['year' => 'ASC', 'city' => 'ASC']);
+    }
+
     //    /**
     //     * @return Conference[] Returns an array of Conference objects
     //     */

Alla fine di questa fase, il sito dovrebbe avere l'aspetto seguente:

/

Andare oltre

  • Il flusso di Request-Response nelle applicazioni Symfony;
  • Gli eventi HTTP predefiniti di Symfony;
  • Gli eventi predefiniti di Symfony Console.
Previous page Creare branch del codice
Next page Gestione del ciclo di vita degli oggetti Doctrine
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

    Show your Sylius expertise

    Show your Sylius expertise

    Peruse our complete Symfony & PHP solutions catalog for your web development needs.

    Peruse our complete Symfony & PHP solutions catalog for your web development needs.

    Version:
    Locale:
    ebook

    This book is backed by:

    see all backers

    Symfony footer

    Avatar of Vlad Gregurco, a Symfony contributor

    Thanks Vlad Gregurco (@vgregurco) for being a Symfony contributor

    10 commits • 290 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