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. Tworzenie kontrolera

Tworzenie kontrolera

Nasz projekt księgi gości jest już dostępny na serwerach produkcyjnych, ale trochę oszukiwaliśmy. Projekt nie posiada jeszcze żadnych podstron. Za stronę główną służy nudny błąd 404. Naprawmy to.

Kiedy przychodzi żądanie HTTP, np. dla strony głównej (http://localhost:8000/), Symfony próbuje znaleźć trasę (ang. route), która pasuje do ścieżki zapytania (tutaj /). Trasa jest łącznikiem pomiędzy ścieżką zapytania i wywoływaczem PHP (ang. PHP callable), funkcją, która tworzy odpowiedź dla tego żądania HTTP.

Te wywoływacze (ang. callable) nazywane są "kontrolerami". W Symfony większość kontrolerów jest zaimplementowana jako klasy PHP. Możesz stworzyć taką klasę ręcznie, ale ponieważ lubimy działać szybko, zobaczmy, jak Symfony może nam pomóc.

Lenistwo zawdzięczane Maker Bundle

Aby wygodnie i szybko wygenerować kontrolery, możemy skorzystać z pakietu symfony/maker-bundle, który został zainstalowany, jako część paczki webapp.

Maker Bundle pomaga wygenerować wiele różnych klas. Będziemy go używać w tej książce cały czas. Każdy "generator" jest definiowany w poleceniu i wszystkie polecenia należą do przestrzeni nazw make.

Wbudowane w Symfony Console polecenie list zawiera listę wszystkich poleceń dostępnych w danej przestrzeni nazw; użyj go, aby odkryć wszystkie generatory dostarczone przez Maker Bundle:

1
$ symfony console list make

Wybieranie formatu konfiguracji

Przed stworzeniem pierwszego kontrolera w projekcie, musimy wybrać format konfiguracyjny, który chcemy wykorzystać. Symfony obsługuje YAML, XML, PHP i atrybuty PHP od razu po instalacji.

Do konfiguracji pakietów najlepszym wyborem jest YAML. Pliki konfiguracyjne znajdują się w katalogu config/. Często, gdy instalujesz nowy pakiet, przepis pakietu (ang. recipe) podczas procesu instalacyjnego doda w tym katalogu nowy plik kończący się rozszerzeniem .yaml.

W przypadku konfiguracji kodu PHP atrybuty są lepszym wyborem, ponieważ są definiowane w ramach kodu. Pozwól, że wyjaśnię to na przykładzie. Kiedy przychodzi żądanie, konfiguracja musi powiedzieć Symfony, że ścieżka żądania powinna być obsługiwana przez określony kontroler (klasa PHP). W przypadku korzystania z formatów konfiguracyjnych YAML, XML lub PHP, potrzebne są dwa pliki (plik konfiguracyjny i plik kontrolera PHP). W przypadku korzystania z atrybutów konfiguracja odbywa się bezpośrednio w klasie kontrolera.

Możesz się zastanawiać, jak odgadnąć nazwę pakietu wymaganego przez dane rozszerzenie? Nie musisz jej znać, gdyż - w większości przypadków - Symfony zawiera nazwę niezbędnego pakietu w komunikatach o błędach. Na przykład uruchamianie symfony console make:message bez pakietu messenger zakończyłoby się wyjątkiem zawierającym podpowiedź o potrzebie zainstalowania właściwego pakietu.

Generowanie kontrolera

Utwórz swój pierwszy kontroler za pomocą polecenia make:controller:

1
$ symfony console make:controller ConferenceController

Polecenie tworzy klasę ConferenceController w katalogu src/Controller/. Wygenerowana klasa zawiera gotowy kod, który możesz modyfikować:

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\Annotation\Route;

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

Atrybut #[Route('/conference', name: 'conference')] jest tym, co czyni metodę index() kontrolerem (konfiguracja znajduje się nad kodem, który konfiguruje).

Po wejściu na adres: /conference w przeglądarce kontroler jest wykonywany, a odpowiedź zwracana.

Dostosuj trasę (ang. route), aby kierowała do strony głównej:

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\Annotation\Route;

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

Parametr nazwy trasy (ang. route) - name - będzie przydatny, gdy chcemy odnieść się do strony głównej w kodzie. Zamiast kodowania ścieżki / na sztywno, użyjemy nazwy trasy.

Zamiast domyślnie renderowanej strony, zwróćmy prostą stronę 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
+        );
     }
 }

Odśwież przeglądarkę:

/

Głównym zadaniem kontrolera jest zwrócenie odpowiedzi HTTP dla żądania.

Ponieważ reszta rozdziału dotyczy kodu, którego nie zachowamy, zatwierdźmy teraz nasze zmiany:

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

Dodawanie Easter Egga

Aby zademonstrować, w jaki sposób odpowiedź może wykorzystać informacje z żądania, dodajmy małego easter egga. Ilekroć strona główna zawiera łańcuch zapytań (ang. query string) taki jak: ?hello=Fabien, dodajmy tekst, aby powitać osobę:

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\Annotation\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 udostępnia dane żądania poprzez obiekt Request. Kiedy widzi argument kontrolera z typem Request, automatycznie wie, jaki obiekt przekazać. Może zostać wykorzystany, aby pobrać element name z łańcucha zapytań i dodać tytuł <h1>.

Otwórz w przeglądarce adres / a następnie /?hello=Fabien i zobacz różnice

Note

Zwróć uwagę na wywołanie funkcji htmlspecialchars(), dzięki czemu unikniemy problemów związanych z XSS. Jest to operacja, która zostanie dla nas wykonana automatycznie po przełączeniu się na odpowiedni silnik szablonów.

Mogliśmy również uczynić z nazwy część adresu 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\Annotation\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));
         }

Część {name} jest dynamicznym parametrem trasy (ang. route parameter) - działa jak symbol wieloznaczny (ang. wildcard). Możesz teraz odwiedzić /hello/Fabien w przeglądarce, aby uzyskać takie same wyniki jak poprzednio. Wartość {name} parametru można uzyskać poprzez dodanie argumentu kontrolera o tej samej nazwie - $name.

Cofnij zmiany, które właśnie wprowadziliśmy:

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

Debugowanie zmiennych

Świetnym narzędziem debugowania jest funkcja Symfony dump(). Jest zawsze dostępna i pozwala zrzucać zmienne w ładnym i interaktywnym formacie.

Zmień na chwilę src/Controller/ConferenceController.php, aby zrzucić obiekt 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\Annotation\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>

Podczas odświeżania strony, zwróć uwagę na nową ikonę „celu” na pasku narzędzi; pozwala ona sprawdzić zmienne, który debugujesz. Kliknij ją, aby uzyskać dostęp do pełnej strony, na której nawigacja jest prostsza:

/

Cofnij zmiany, które właśnie wprowadziliśmy:

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

Idąc dalej

  • System trasowania Symfony;
  • Samouczek SymfonyCasts: routing, kontrolery i strony;
  • Atrybuty w PHP;
  • Komponent HttpFoundation;
  • Ataki XSS (Cross-Site Scripting);
  • Ściągawka Symfony Routing.
Previous page Rozwiązywanie problemów
Next page Konfigurowanie bazy danych
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

    Symfony Code Performance Profiling

    Symfony Code Performance Profiling

    Be trained by SensioLabs experts (2 to 6 day sessions -- French or English).

    Be trained by SensioLabs experts (2 to 6 day sessions -- French or English).

    Version:
    Locale:
    ebook

    This book is backed by:

    see all backers

    Symfony footer

    Avatar of Tristan Maindron, a Symfony contributor

    Thanks Tristan Maindron (@tmaindron) for being a Symfony contributor

    2 commits • 149 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