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. Polish
  5. Nasłuchiwanie zdarzeń

Nasłuchiwanie zdarzeń

W obecnym szablonie brakuje nagłówka nawigacyjnego, który umożliwi powrót na stronę główną lub przejście do kolejnej konferencji.

Dodawanie nagłówka strony

Elementy wyświetlane na wszystkich stronach aplikacji, jak nagłówek strony, powinny zostać zawarte w szablonie bazowym:

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
@@ -14,6 +14,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>

Dodanie tego kodu do szablonu oznacza, że wszystkie szablony rozszerzające go muszą zdefiniować zmienną o nazwie conferences, której wartość musi zostać utworzona i przekazana z poziomu kontrolerów.

Ponieważ mamy tylko dwa kontrolery, możesz wykonać następujące czynności (nie stosuj zmiany w kodzie, ponieważ wkrótce nauczymy się lepszego sposobu):

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
@@ -29,12 +29,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 new Response($this->twig->render('conference/show.html.twig', [
+            'conferences' => $conferenceRepository->findAll(),
             'conference' => $conference,
             'comments' => $paginator,
             'previous' => $offset - CommentRepository::PAGINATOR_PER_PAGE,

Wyobraź sobie, że musisz wprowadzić zmianę w dziesiątkach istniejących kontrolerów, a także we wszystkich nowo utworzonych. Nie jest to zbyt praktyczne, musi istnieć lepszy sposób.

Twig pozwala na tworzenie zmiennych globalnych. Zmienna globalna jest dostępna we wszystkich renderowanych szablonach. Można je zdefiniować w pliku konfiguracyjnym, ale zadziała to tylko w przypadku wartości statycznych. Aby przekazać wszystkie konferencje jako zmienną globalną w Twig, stworzymy nasłuchiwacz zdarzeń (ang. event listener).

Odkrywanie zdarzeń Symfony

Symfony posiada wbudowany komponent dyspozytora zdarzeń (ang. event dispatcher). Dyspozytor zdarzeń w odpowiednich momentach emituje określone zdarzenia, które mogą być nasłuchiwane przez nasłuchiwaczy zdarzeń. Nasłuchiwacze zdarzeń umożliwiają w tym przypadku wywołanie kodu w odpowiedzi na zdarzenia wyemitowane przez wewnętrzne mechanizmy frameworka.

Na przykład, niektóre zdarzenia pozwalają na interakcję z cyklem życia żądań HTTP. Podczas obsługi żądania dyspozytor zdarzeń emituje zdarzenia, gdy żądanie zostało utworzone, gdy kod kontrolera ma zostać wykonany, gdy odpowiedź jest gotowa do wysłania, lub gdy został rzucony wyjątek. Nasłuchiwacz zdarzeń może oczekiwać jednego lub kilku zdarzeń i wykonywać działania w oparciu o kontekst przekazany w obiekcie zdarzenia.

Zdarzenia są elementami frameworka, które czynią go łatwo rozszerzalnym i bardziej elastycznym. Wiele komponentów Symfony, takich jak Security, Messenger, Workflow czy Mailer, używa ich w szerokim zakresie.

Inny przykład użycia wbudowanego we framework mechanizmu zdarzeń i nasłuchiwaczy zdarzeń powiązany jest z cyklem życia poleceń (ang. commands): możesz utworzyć nasłuchiwacz zdarzeń, który wykona kod przed uruchomieniem jakiegolwiek polecenia Symfony.

Dowolny rodzaj rozszerzenia, jak paczka lub pakiet, może emitować własne typy zdarzeń, co czyni jego kod łatwo rozszerzalnym.

Aby uniknąć posiadania pliku konfiguracyjnego opisującego zdarzenia, których nasłuchiwacz zdarzeń chce nasłuchiwać, utwórz subskrybenta zdarzeń (ang. event subscriber). Subskrybent zdarzeń jest rodzajem nasłuchiwacza zdarzeń posiadającym statyczną metodę getSubscribedEvents(), która zwraca jego konfigurację. Dzięki temu subskrybent może być automatycznie zarejestrowany w dyspozytorze zdarzeń Symfony.

Implementacja subskrybenta zdarzeń

Znasz już tę śpiewkę – użyj Maker Bundle, aby wygenerować subskrybenta zdarzeń:

1
$ symfony console make:subscriber TwigEventSubscriber

Polecenie zapyta o to, jakich zdarzeń chcesz nasłuchiwać. Wybierz zdarzenie typu Symfony\Component\HttpKernel\Event\ControllerEvent, które jest emitowane tuż przed wykonaniem kodu kontrolera. Jest to najlepszy moment na wstrzyknięcie globalnej zmiennej conferences w taki sposób, aby Twig miał do niej dostęp, kiedy kontroler będzie renderował szablon. Zaktualizuj swojego subskrybenta zdarzeń w następujący sposób:

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)
     {
-        // ...
+        $this->twig->addGlobal('conferences', $this->conferenceRepository->findAll());
     }

     public static function getSubscribedEvents()

Teraz możesz dodać dowolną liczbę kontrolerów: zmienna conferences będzie zawsze dostępna w szablonach Twig.

Note

W dalszej części książki rozważymy znacznie lepsze i bardziej wydajne rozwiązanie.

Sortowanie konferencji według roku i miasta

Sortowanie listy konferencji według roku ułatwi jej przeglądanie. Moglibyśmy stworzyć własną metodę pobierania i sortowania wszystkich konferencji, ale zamiast tego zastąpimy domyślną implementację metody findAll(), aby upewnić się, że sortowanie będzie użyte we wszystkich wymaganych miejscach:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
--- a/src/Repository/ConferenceRepository.php
+++ b/src/Repository/ConferenceRepository.php
@@ -19,6 +19,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
     //  */

Na koniec tego etapu strona aplikacji powinna wyglądać następująco:

/

Idąc dalej

  • Cykl życia Request-Response w aplikacjach Symfony;
  • Wbudowane zdarzenia Symfony HTTP;
  • Wbudowane zdarzenia Symfony Console.
Previous page Zarządzanie gałęziami kodu
Next page Zarządzanie cyklem życia obiektów Doctrine
This work, including the code samples, is licensed under a Creative Commons BY-NC-SA 4.0 license.
TOC
    Version

    Symfony 5.4 is backed by

    Measure & Improve Symfony Code Performance

    Measure & Improve Symfony Code Performance

    Get your Sylius expertise recognized

    Get your Sylius expertise recognized

    Version:
    Locale:
    ebook

    This book is backed by:

    see all backers

    Symfony footer

    Avatar of Ilia Lazarev, a Symfony contributor

    Thanks Ilia Lazarev (@ilzrv) for being a Symfony contributor

    1 commit • 2 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