162 89 5MB
Polish Pages 487 Year 2012
Spis treści Podziękowania .............................................................................. 13
Część I Rozdział 1.
Tworzenie prostych stron WWW .................................... 15 Uruchomienie przykładowego projektu ........................................... 17 Dystrybucja with vendors — około 6 MB ....................................................................... 17 Dystrybucja without vendors — około 200 kB ............................................................. 17 Przykład 1.1. Aplikacja przykładowa ............................................................................ 18 ROZWIĄZANIE ..................................................................................................... 18 Podsumowanie .............................................................................................................. 22
Rozdział 2.
Hello, world! .................................................................................. 25 Przestrzenie nazw .......................................................................................................... 25 Pakiet ............................................................................................................................. 26 Kontroler i akcja ............................................................................................................ 27 Widok ............................................................................................................................ 28 Przykład 2.1. Hello, world! ........................................................................................... 28 ROZWIĄZANIE ..................................................................................................... 28 Zmodyfikowane pliki .................................................................................................... 39 Środowiska pracy .......................................................................................................... 40 Tworzenie i usuwanie pakietów .................................................................................... 42 Użycie przestrzeni nazewniczych .................................................................................. 42 Cechy Symfony 2 .......................................................................................................... 44 Formaty konfiguracji ............................................................................................... 44 Uruchomienie gotowego przykładu ............................................................................... 46
Rozdział 3.
Dołączanie zewnętrznych zasobów ................................................. 47 Przykład 3.1. Pusta Dolinka .......................................................................................... 49 ROZWIĄZANIE ..................................................................................................... 49 Przykład 3.2. Dolina Pięciu Stawów Polskich ............................................................... 53 ROZWIĄZANIE ..................................................................................................... 53
Rozdział 4.
Szablon witryny ............................................................................. 57 Przykład 4.1. Dwa kabele .............................................................................................. 60 ROZWIĄZANIE ..................................................................................................... 61
Rozdział 5.
Hiperłącza i struktura aplikacji ...................................................... 65 Tworzenie i usuwanie akcji ........................................................................................... 65 Tworzenie i usuwanie kontrolerów ............................................................................... 67
4
Symfony 2 od podstaw Tworzenie i usuwanie pakietów .................................................................................... 67 Definiowanie adresów URL akcji ................................................................................. 68 Przykład 5.1. Fraszki ..................................................................................................... 69 ROZWIĄZANIE ..................................................................................................... 69 Przykład 5.2. Zabytki Lublina ....................................................................................... 72 ROZWIĄZANIE ..................................................................................................... 74 Przykład 5.3. Piosenki dla dzieci ................................................................................... 77 ROZWIĄZANIE ..................................................................................................... 78
Rozdział 6.
Błędy 404 ..................................................................................... 83 Strony błędów w Symfony 2 ......................................................................................... 84 Przykład 6.1. Gady ........................................................................................................ 86 ROZWIĄZANIE ..................................................................................................... 86 Nadpisywanie widoków dowolnych pakietów .............................................................. 91 Programowe generowanie błędów 404 oraz 500 ........................................................... 92
Rozdział 7.
Publikowanie projektu na serwerze hostingowym ........................... 93 Przykład 7.1. Gady — wersja lokalna z własną domeną ............................................... 93 ROZWIĄZANIE ..................................................................................................... 94 Przykład 7.2. Gady — wersja z serwera firmy NetArt .................................................. 95 ROZWIĄZANIE ..................................................................................................... 95 Przykład 7.3. Gady — wersja z serwera firmy Light Hosting ....................................... 97 ROZWIĄZANIE ..................................................................................................... 97
Rozdział 8.
Podsumowanie części I ............................................................... 101 Dystrybucje Symfony 2 ............................................................................................... 101 Przykładowa aplikacja ACME demo .......................................................................... 101 Pierwszy samodzielnie wykonany projekt ................................................................... 102 Zewnętrzne zasoby ...................................................................................................... 103 Szablon witryny .......................................................................................................... 103 Podstawy routingu ....................................................................................................... 104 Błędy 404 .................................................................................................................... 104 Publikowanie projektu ................................................................................................. 105 Przykład 8.1. Przygotowanie pakietu symfony2-customized-v1.zip (bez przykładu src/Acme) ......................................................................................... 106 ROZWIĄZANIE ................................................................................................... 106
Część II
Widoki ....................................................................... 109
Rozdział 9.
Twig ........................................................................................... 111 Logiczne nazwy widoków ........................................................................................... 111 Nadpisywanie widoków z folderu vendor ................................................................... 113 Nazwy widoków akcji ................................................................................................. 114 Przykład 9.1. Nazwy logiczne widoków, adnotacja @Template() i metoda render() ....... 116 ROZWIĄZANIE ................................................................................................... 116 Składnia widoków Twig .............................................................................................. 119 Wyłączanie interpretacji w szablonie .......................................................................... 120 Przykład 9.2. Wyłączanie interpretacji fragmentu szablonu ........................................ 121 ROZWIĄZANIE ................................................................................................... 122 Podwójne rozszerzenie .html.twig ............................................................................... 123 Modyfikacja nagłówka Content-Type przy użyciu parametru _format ................. 124 Modyfikacja nagłówka Content-Type metodą set() .............................................. 124 Przykład 9.3. Modyfikacja nagłówka Content-Type ................................................... 125 ROZWIĄZANIE ................................................................................................... 125
Spis treści
5
Rozdział 10. Zmienne, wyrażenia i operatory Twig ........................................... 129 Przekazywanie zmiennych do widoku ........................................................................ 129 Przykład 10.1. Data i godzina ...................................................................................... 130 ROZWIĄZANIE ................................................................................................... 131 Zabezpieczanie zmiennych .......................................................................................... 132 Przykład 10.2. Zabezpieczanie zmiennych .................................................................. 134 ROZWIĄZANIE ................................................................................................... 135 Przekazywanie do widoku tablic ................................................................................. 138 Przekazywanie do widoku obiektów ........................................................................... 139 Wyrażenia Twig .......................................................................................................... 139 Operatory Twig ........................................................................................................... 141 Definiowanie zmiennych wewnątrz widoku ................................................................ 144 Zmienne globalne ........................................................................................................ 145
Rozdział 11. Instrukcje sterujące for oraz if ..................................................... 147 Instrukcja for ............................................................................................................... 147 Instrukcja if ................................................................................................................. 150 Przykład 11.1. Korona ziemi ....................................................................................... 151 ROZWIĄZANIE ................................................................................................... 152 Przykład 11.2. Dzieła literatury światowej .................................................................. 155 ROZWIĄZANIE ................................................................................................... 155 Przykład 11.3. Tabliczka mnożenia ............................................................................. 157 ROZWIĄZANIE ................................................................................................... 157 Przykład 11.4. Tabela potęg ........................................................................................ 161 ROZWIĄZANIE ................................................................................................... 161 Przykład 11.5. Bezpieczna paleta kolorów .................................................................. 163 ROZWIĄZANIE ................................................................................................... 164
Rozdział 12. Znaczniki, filtry i funkcje ............................................................. 169 Znaczniki Twig ........................................................................................................... 169 Znaczniki for oraz if .............................................................................................. 171 Znaczniki macro, from i import ............................................................................ 171 Znacznik filter ....................................................................................................... 172 Znacznik set .......................................................................................................... 173 Znacznik extends ................................................................................................... 173 Znacznik block ...................................................................................................... 175 Znaczniki extends i block oraz dziedziczenie ....................................................... 175 Znacznik use ......................................................................................................... 178 Znacznik include ................................................................................................... 179 Znacznik spaceless ................................................................................................ 179 Znacznik autoescape ............................................................................................. 180 Znacznik raw ......................................................................................................... 180 Znacznik flush ....................................................................................................... 180 Znacznik do ........................................................................................................... 180 Znacznik render ..................................................................................................... 181 Filtry ............................................................................................................................ 181 Funkcje ........................................................................................................................ 184 Przykład 12.1. Piosenki dziecięce ............................................................................... 185 ROZWIĄZANIE ................................................................................................... 186
Rozdział 13. Trójstopniowy podział widoków .................................................... 195 Przykład 13.1. Opowiadania Edgara Allana Poe ......................................................... 197 ROZWIĄZANIE ................................................................................................... 198
Rozdział 14. Podsumowanie części II .............................................................. 205
6
Symfony 2 od podstaw
Część III Dostosowywanie Symfony 2 ........................................ 207 Rozdział 15. Dodawanie nowych pakietów ....................................................... 209 Lista pakietów zawartych w Symfony ......................................................................... 209 Zawartość folderu vendor/ ........................................................................................... 210 Pobieranie pakietów do folderu vendor/ .......................................................................... 211 Dołączanie pakietów do kodu ..................................................................................... 212 Przykład 15.1. Przygotowanie dystrybucji symfony2-customized-v2 zawierającej pakiet DoctrineFixturesBundle ............................................................ 212 ROZWIĄZANIE ................................................................................................... 213
Rozdział 16. Podsumowanie części III ............................................................. 217
Część IV Praca z bazą danych ................................................... 219 Rozdział 17. Pierwszy projekt wykorzystujący bazę danych .............................. 221 Przykład 17.1. Imiona ................................................................................................. 221 ROZWIĄZANIE ................................................................................................... 222
Rozdział 18. ORM Doctrine 2 .......................................................................... 233 Tworzenie i usuwanie bazy danych ............................................................................. 233 Doctrine 2.1 ................................................................................................................. 234 Tworzenie tabel w bazie danych ................................................................................. 235 Struktura klas dostępu do bazy danych ....................................................................... 236 Dodawanie nowych właściwości do istniejącej klasy ................................................. 237 Typy danych ................................................................................................................ 238 Operowanie klasami dostępu do bazy danych ............................................................. 240 Klasy Entity i EntityManager ................................................................................ 240 Stan obiektu Entity ................................................................................................ 241 Tworzenie nowych rekordów ................................................................................ 242 Usuwanie rekordów .............................................................................................. 243 Pobieranie wszystkich rekordów z bazy ................................................................ 243 Przykład 18.1. Rzeki ................................................................................................... 243 ROZWIĄZANIE ................................................................................................... 244
Rozdział 19. Dostosowywanie klas dostępu do bazy danych ............................. 251 Klasy Entity oraz Repository ....................................................................................... 251 Podstawowe metody klas Repository .......................................................................... 252 Metoda find() ........................................................................................................ 252 Metoda findAll() ................................................................................................... 253 Metoda findBy() .................................................................................................... 253 Metoda findOneBy() ............................................................................................. 254 Metoda findByX() ................................................................................................. 254 Metoda findOneByX() .......................................................................................... 255 Nadpisywanie metod klasy Entity ............................................................................... 255 Metoda __toString() klasy Entity .......................................................................... 255 Metoda fromArray () klasy Entity ......................................................................... 256 Nadpisywanie metod klasy Repository ....................................................................... 256 Przykład 19.1. Tatry .................................................................................................... 257 ROZWIĄZANIE ................................................................................................... 257
Rozdział 20. Podsumowanie części IV ............................................................. 265
Spis treści
7
Część V
Zachowania Doctrine ................................................. 267
Rozdział 21. Instalacja i konfiguracja rozszerzeń DoctrineExtensions ................ 269 Przykład 21.1. Przygotowanie dystrybucji symfony2-customized-v3 zawierającej pakiet StofDoctrineExtensionsBundle .................................................. 270 ROZWIĄZANIE ................................................................................................... 270
Rozdział 22. Zachowanie sluggable ................................................................. 275 Identyfikatory slug ...................................................................................................... 275 Automatyczne generowanie identyfikatorów slug w Symfony 2 ................................ 276 Przykład 22.1. Wyrazy — test zachowania sluggable ................................................. 277 ROZWIĄZANIE ................................................................................................... 277 Parametry adnotacji konfigurujących wartości slug .................................................... 280
Rozdział 23. Zachowanie timestampable ......................................................... 281 Przykład 23.1. Wyrazy — test zachowania timestampable ......................................... 282 ROZWIĄZANIE ................................................................................................... 282
Rozdział 24. Zachowanie translatable ............................................................. 283 Wstawianie tłumaczeń do bazy danych ....................................................................... 284 Odczytywanie tłumaczeń ............................................................................................ 286 Przykład 24.1. Kolory — test zachowania timestampable .......................................... 286 ROZWIĄZANIE ................................................................................................... 287
Rozdział 25. Podsumowanie części V .............................................................. 293
Część VI Szczegółowe dane rekordu .......................................... 295 Rozdział 26. Akcja show ................................................................................. 297 Adresy URL zawierające zmienne .............................................................................. 297 Konwersja wejściowa ............................................................................................ 298 Konwersja wyjściowa ........................................................................................... 298 Wyszukiwanie pojedynczego rekordu na podstawie klucza głównego ....................... 298 Wyświetlanie właściwości rekordu ............................................................................. 299 Przykład 26.1. Piosenki wojskowe .............................................................................. 299 ROZWIĄZANIE ................................................................................................... 300
Rozdział 27. Identyfikacja rekordu na podstawie wartości slug ........................ 307 Przykład 27.1. Piosenki wojskowe — użycie identyfikatorów slug ............................ 308 ROZWIĄZANIE ................................................................................................... 308
Rozdział 28. Generowanie menu na podstawie zawartości bazy danych ............ 311 Przykład 28.1. Treny ................................................................................................... 311 ROZWIĄZANIE ................................................................................................... 312
Rozdział 29. Udostępnianie plików binarnych ................................................... 319 Przykład 29.1. Download — pliki zapisane w bazie danych ....................................... 320 ROZWIĄZANIE ................................................................................................... 320 Przykład 29.2. Download — pliki pobierane z folderu ............................................... 325 ROZWIĄZANIE ................................................................................................... 325
Rozdział 30. Podsumowanie części VI ............................................................. 327
8
Symfony 2 od podstaw
Część VII Relacje ...................................................................... 329 Rozdział 31. Relacje 1:1 ................................................................................. 331 Klucze obce o wartości NULL .................................................................................... 332 Użycie relacji 1:1 w Symfony 2 .................................................................................. 332 Operowanie rekordami powiązanymi relacją .............................................................. 334 Tworzenie rekordów ............................................................................................. 334 Rekord zależny ...................................................................................................... 335 Przykład 31.1. Dane użytkowników ............................................................................ 335 ROZWIĄZANIE ................................................................................................... 335 Akcje referencyjne SQL .............................................................................................. 338 Programowe akcje referencyjne Doctrine 2.1 .............................................................. 339 Parametr cascade ................................................................................................... 339 Parametr orphanRemoval ...................................................................................... 340 Relacje jednokierunkowe i dwukierunkowe ................................................................ 340 Synchronizacja obiektów z bazą danych ........................................................................ 342
Rozdział 32. Relacje 1:n (jeden do wielu) ........................................................ 345 Klucze obce o wartości NULL .................................................................................... 346 Użycie relacji 1:n w Symfony 2 .................................................................................. 346 Właściciel relacji 1:n ................................................................................................... 349 Operowanie rekordami powiązanymi relacją .............................................................. 349 Tworzenie rekordów ............................................................................................. 349 Rekordy zależne .................................................................................................... 350 Rekord nadrzędny ................................................................................................. 351 Synchronizacja relacji ................................................................................................. 351 Akcje referencyjne ...................................................................................................... 352 Akcje SQL-owe ..................................................................................................... 352 Akcje Doctrine ...................................................................................................... 352 Przykład 32.1. Kontynent i państwa ............................................................................ 353 ROZWIĄZANIE ................................................................................................... 353 Porządkowanie rekordów ............................................................................................ 357
Rozdział 33. Relacje n:m (wiele do wielu) ........................................................ 359 Użycie relacji n:m w Symfony 2 ................................................................................. 360 Właściciel relacji n:m .................................................................................................. 361 Tabela łącząca relacji n:m ........................................................................................... 362 Operowanie rekordami powiązanymi relacją .............................................................. 362 Tworzenie rekordów ............................................................................................. 362 Rekordy zależne .................................................................................................... 363 Synchronizacja relacji ........................................................................................... 364 Usuwanie powiązania relacyjnego ........................................................................ 364 Akcje referencyjne SQL .............................................................................................. 365 Akcje SQL-owe ..................................................................................................... 365 Przykład 33.1. Filmy i aktorzy .................................................................................... 365 ROZWIĄZANIE ................................................................................................... 365 Porządkowanie rekordów ............................................................................................ 370
Rozdział 34. Relacje, akcje index i show oraz widoki częściowe ....................... 373 Przykład 34.1. Kontynenty/Państwa — akcje show i widoki częściowe ..................... 375 Przykład 34.2. Filmy/Aktorzy — akcje show i widoki częściowe .............................. 376 Przykład 34.3. Powieści Agaty Christie ...................................................................... 376 ROZWIĄZANIE ................................................................................................... 377
Spis treści
9
Rozdział 35. Podsumowanie części VII ............................................................ 385
Część VIII Panele CRUD i zabezpieczanie dostępu do aplikacji .... 387 Rozdział 36. Generowanie paneli administracyjnych CRUD ............................... 389 Adresy URL akcji CRUD ..................................................................................... 391 Ponowne generowanie paneli CRUD .......................................................................... 394 Panele CRUD a relacje ................................................................................................ 394 Przykład 36.1. Imiona — panel CRUD ....................................................................... 394 ROZWIĄZANIE ................................................................................................... 395 Przykład 36.2. Panel CRUD i relacja 1:1 .................................................................... 396 ROZWIĄZANIE ................................................................................................... 396 Przykład 36.3. Panel CRUD i relacja 1:n .................................................................... 399 ROZWIĄZANIE ................................................................................................... 399 Przykład 36.4. Panel CRUD i relacja n:m ...................................................................... 401 ROZWIĄZANIE ................................................................................................... 401
Rozdział 37. Instalacja pakietu FOSUserBundle ............................................... 403 Przykład 37.1. Przygotowanie dystrybucji symfony2-customized-v4 zawierającej pakiet FOSUserBundle ......................................................................... 403 ROZWIĄZANIE ................................................................................................... 403 Tworzenie kont i nadawanie uprawnień ...................................................................... 408 Tworzenie kont ..................................................................................................... 409 Aktywacja i deaktywacja konta ............................................................................. 409 Nadawanie i usuwanie uprawnień administracyjnych ........................................... 409 Przykład 37.2. Sprawdzenie działania dystrybucji symfony2-customized-v4 ............. 410 ROZWIĄZANIE ................................................................................................... 410
Rozdział 38. Aplikacja dostępna wyłącznie dla zdefiniowanych użytkowników ...... 415 Uprawnienia dostępu ................................................................................................... 415 Role użytkowników ..................................................................................................... 416 Nadawanie, usuwanie i sprawdzanie uprawnień użytkownikom ................................. 417 Przykład 38.1. Korona ziemi ....................................................................................... 419 ROZWIĄZANIE ................................................................................................... 420 Hierarchia ról .............................................................................................................. 427
Rozdział 39. Aplikacja dostępna publicznie w trybie do odczytu ........................ 429 Przykład 39.1. Korona ziemi — podział na frontend oraz backend ............................ 429 ROZWIĄZANIE ................................................................................................... 430 Przekierowania ............................................................................................................ 432 Osadzanie formularza do logowania na stronie głównej ............................................. 434 Przykład 39.2. Korona ziemi — osadzenie formularza do logowania w pliku base.html.twig ........................................................................................................... 435 ROZWIĄZANIE ................................................................................................... 435
Rozdział 40. Rejestracja użytkowników i odzyskiwanie hasła ........................... 439 Przykład 40.1. Kontynenty/państwa — frontend i backend ........................................ 439 ROZWIĄZANIE ................................................................................................... 439 Przykład 40.2. Kontynenty/państwa — rejestracja użytkowników ............................. 442 ROZWIĄZANIE ................................................................................................... 442 Przykład 40.3. Kontynenty/państwa — odzyskiwanie hasła ....................................... 444 ROZWIĄZANIE ................................................................................................... 444
Rozdział 41. Podsumowanie części VIII ........................................................... 447
10
Symfony 2 od podstaw
Część IX Panele administracyjne Sonata ................................... 449 Rozdział 42. Instalacja pakietów Sonata .............................................................. 451 Przykład 42.1. Przygotowanie dystrybucji symfony2-customized-v5 zawierającej pakiet SonataAdminBundle .................................................................. 451 ROZWIĄZANIE ................................................................................................... 452 Krok 1. Wypakuj dystrybucję Symfony 2.0.X without vendors ............................ 452 Krok 2. Zmodyfikuj plik deps ............................................................................... 452 Krok 3. Pobierz pakiety ......................................................................................... 453 Krok 4. Usuń foldery .git ...................................................................................... 453 Krok 5. Zarejestruj przestrzenie nazw ................................................................... 453 Krok 6. Zarejestruj pakiety .................................................................................... 454 Krok 7. Zmodyfikuj konfigurację projektu ........................................................... 454 Krok 8. Zmodyfikuj zabezpieczenia projektu ....................................................... 455 Krok 9. Utwórz pakiet Application/Sonata/UserBundle ....................................... 457 Krok 10. Zmodyfikuj reguły routingu ................................................................... 457 Krok 11. Zainstaluj style CSS oraz ikony ............................................................. 458 Krok 12. Skompresuj otrzymaną dystrybucję ....................................................... 458 Przykład 42.2. Sprawdź działanie dystrybucji symfony2-customized-v5 ................... 458 ROZWIĄZANIE ................................................................................................... 459 Krok 1. Wypakuj dystrybucję i skonfiguruj bazę danych ..................................... 459 Krok 2. Utwórz tabele w bazie danych ................................................................. 459 Krok 3. Utwórz konto administratora .................................................................... 459 Krok 4. Sprawdź wygląd panelu administracyjnego ............................................. 459
Rozdział 43. Użycie paneli administracyjnych Sonata do własnych tabel ............. 461 Przykład 43.1. Miasta .................................................................................................. 461 ROZWIĄZANIE ................................................................................................... 462 Krok 1. Wypakuj dystrybucję i skonfiguruj bazę danych ..................................... 462 Krok 2. Utwórz pakiet My/Frontend ..................................................................... 462 Krok 3. Utwórz klasę CityAdmin .......................................................................... 462 Krok 4. Włącz panel administracyjny do zarządzania rekordami City .................. 463 Krok 5. Przygotuj plik zawierający tłumaczenia ................................................... 464 Krok 6. Sprawdź wygląd panelu administracyjnego do edycji miast .................... 464
Rozdział 44. Podsumowanie części IX ............................................................. 467 Przykład 44.1. Przygotowanie dystrybucji symfony2-customized-v6 zawierającej omówione pakiety ................................................................................ 467 Przykład 44.2. Rzeki: aplikacja z panelem Sonata ...................................................... 468 ROZWIĄZANIE ................................................................................................... 468 Krok 1. Połącz przykład 18. z dystrybucją symfony2-customized-v6.zip ............. 468 Krok 2. Wykonaj panel Sonata ............................................................................. 469 Przykład 44.3. Kontynenty: aplikacja z panelem Sonata ............................................. 469 ROZWIĄZANIE ................................................................................................... 469 Przykład 44.4. Filmy: aplikacja z panelem Sonata ...................................................... 470 Przykład 44.5. Powieści Agaty Christie: aplikacja z panelem Sonata ......................... 470
Dodatki ..................................................................... 471 Dodatek A
Instalacja oprogramowania .......................................................... 473 1. XAMPP ................................................................................................................... 473 2. Modyfikacja konfiguracji PHP ................................................................................ 475 3. Modyfikacja pakietu PEAR ..................................................................................... 476 4. Uaktualnienie biblioteki PEAR ............................................................................... 476
Spis treści
11 5. Code Sniffer ............................................................................................................ 477 6. phpDocumentor ....................................................................................................... 477 7. PHPUnit .................................................................................................................. 477 8. Cygwin .................................................................................................................... 478 9. Ścieżki dostępu ........................................................................................................ 480 10. GraphViz ............................................................................................................... 482 11. NetBeans ............................................................................................................... 482
Skorowidz ................................................................................... 483
12
Symfony 2 od podstaw
.
Podziękowania Serdecznie dziękuję: Fabienowi Potencierowi i wszystkim programistom biorącym udział w rozwoju
Symfony 2 za wysiłek włożony w opracowanie, udokumentowanie i bezpłatne udostępnienie wspaniałego oprogramowania; pracownikom Wydawnictwa Helion, szczególnie Pani Redaktor Ewelinie Burskiej,
za cierpliwość i profesjonalizm; studentom Katolickiego Uniwersytetu Lubelskiego im. Jana Pawła II, którzy
w latach 2011 – 2012 uczestniczyli w prowadzonych przeze mnie zajęciach dotyczących Symfony 2; uczestnikom organizowanych przeze mnie szkoleń: Wojciechowi Cupie,
Mateuszowi Draganowi, Tomaszowi Fudali, Andrzejowi Krynieckiemu, Wojciechowi Matyśkiewiczowi, Piotrowi Piskozubowi, Albertowi Rybackiemu, Ireneuszowi Sachowi, Pawłowi Zalechowi, Michałowi Zboinie oraz Pawłowi Zdyblowi, za opinie na temat materiału, który posłużył do opracowania niniejszego podręcznika; moim najbliższym za wsparcie i mobilizację.
Włodzimierz Gajda Lublin, 20 maja 2012 r.
14
Symfony 2 od podstaw
Część I
Tworzenie prostych stron WWW
16
Część I ♦ Tworzenie prostych stron WWW
Rozdział 1. ♦ Uruchomienie przykładowego projektu
17
Rozdział 1.
Uruchomienie przykładowego projektu Oprogramowanie Symfony 2 jest dostępne w postaci dwóch różnych dystrybucji: Symfony Standard with vendors, nazwa pliku: Symfony_Standard_Vendors_2.0.x.zip; Symfony Standard without vendors, nazwa pliku: Symfony_Standard_2.0.x.zip.
Dystrybucje te różnią się wyłącznie zawartością folderu vendor/.
Dystrybucja with vendors — około 6 MB Dystrybucja with vendors zawiera w folderze vendor/ komplet niezbędnych bibliotek. Plik ten zajmuje ok. 6 MB i jest to gotowa aplikacja Symfony 2, którą możemy uruchomić. Dystrybucja Symfony 2.0 with vendors jest odpowiednikiem dystrybucji sandbox z Symfony 1.4.
Dystrybucja without vendors — około 200 kB Dystrybucja without vendors nie zawiera folderu vendor/. Zanim uruchomimy projekt oparty na tej dystrybucji, musimy doinstalować wszystkie niezbędne pakiety. W początkowym okresie nauki będziemy wykorzystywali dystrybucję with vendors. Dystrybucja without vendors stanie się przydatna, gdy zaczniemy wykorzystywać dodatkowe pakiety.
Część I ♦ Tworzenie prostych stron WWW
18
Po odwiedzeniu strony http://symfony.com/download pobierz najnowszą wersję dystrybucji with vendors. W chwili pisania tego tekstu był to plik Symfony_Standard_Vendors_ 2.0.10.zip.
Przykład 1.1. Aplikacja przykładowa Zanim przejdziemy do nauki Symfony 2, upewnijmy się, że stanowisko pracy jest poprawnie skonfigurowane. W tym celu wystarczy uruchomić aplikację przykładową, która jest zawarta wewnątrz dystrybucji Symfony 2.
ROZWIĄZANIE Krok 1. Utwórz nowy projekt Symfony 2 W folderze przeznaczonym na aplikacje WWW1 utwórz folder Symfony/. Do folderu tego wypakuj zawartość archiwum Symfony_Standard_Vendors_2.0.X.zip2. Po wykonaniu tej operacji zawartość folderu Symfony/ powinna być taka jak na rysunku 1.1. Rysunek 1.1. Katalogi i pliki utworzone po wypakowaniu archiwum Symfony_Standard_ Vendors_2.0.X.zip
Poszczególne foldery widoczne na rysunku 1.1 zawierają: app/ — pliki konfiguracyjne aplikacji; bin/ — polecenia wsadowe dotyczące pakietów dodatkowych (polecenie bin/vendors wykorzystamy m.in. do instalacji pakietu doctrine-fixtures
ułatwiającego wypełnianie bazy danych rekordami); src/ — kod źródłowy aplikacji; vendor/ — pakiety dodatkowe, m.in.: 1
Procedura instalacji oprogramowania jest przedstawiona w dodatku A. Jeśli przygotowałeś stanowisko pracy zgodnie z podanym opisem, to tym folderem jest C:\xampp\htdocs\.
2
W chwili pisania książki najnowszą dostępną wersją była wersja Symfony_Standard_Vendors_2.0.10.zip. Wszystkie podane przykłady zostały wykonane w wersji 2.0.10. Symfony 2 jest obecnie rozwijane i w chwili wydania książki dostępne będą z pewnością nowe wersje.
Rozdział 1. ♦ Uruchomienie przykładowego projektu
19
doctrine — oprogramowanie ORM zapewniające dostęp do bazy danych; twig — system szablonów; swiftmailer — biblioteka ułatwiająca wysyłanie poczty elektronicznej; web/ — folder zawierający główny kontroler aplikacji — skrypt app.php
(ang. front controller), style CSS, pliki graficzne oraz pliki JavaScript (jest to jedyny folder, który jest dostępny publicznie za pomocą protokołu HTTP). Statyczne pliki zawarte w folderze web/ (m.in style .css, skrypty .js oraz pliki graficzne .jpg i .gif) są w oryginalnej dokumentacji określane wspólnym terminem assets.
W folderze web/ znajdują się trzy pliki PHP: web/app.php, web/app_dev.php, web/config.php.
Skrypt app.php uruchamia aplikację w środowisku produkcyjnym3, a skrypt app_dev.php — w środowisku deweloperskim. Skrypt config.php sprawdza natomiast, czy zainstalowane oprogramowanie spełnia minimalne wymagania stawiane przez Symfony 2. Podane trzy skrypty są dostępne pod adresami: http://localhost/Symfony/web/config.php http://localhost/Symfony/web/app.php http://localhost/Symfony/web/app_dev.php
Krok 2. Sprawdź wygląd strony web/app_dev.php Uruchom przeglądarkę i odwiedź w niej adres: http://localhost/Symfony/web/app_dev.php Powinieneś ujrzeć stronę przedstawioną na rysunku 1.2. Zanim przejdziesz do kolejnego rozdziału, musisz poprawnie wyświetlić stronę z rysunku 1.2.
Błędy, które mogą wystąpić Podczas wyświetlania strony z rysunku 1.2 mogą wystąpić następujące błędy: Zainstalowane oprogramowanie nie spełnia wymagań Symfony 2. Podjęto próbę dostępu do skryptu hello-world/web/app_dev.php poprzez sieć. 3
Więcej o środowiskach w kolejnym rozdziale.
Część I ♦ Tworzenie prostych stron WWW
20
Rysunek 1.2. Strona o adresie web/app_dev.php Folder hello-world/app/cache/ zawiera nieaktualną wersję plików i wymaga
odświeżenia. Akcelerator4 zapamiętał niepoprawne ścieżki do plików.
Błąd: zbyt stare oprogramowanie Jeśli po odwiedzeniu adresu: http://localhost/Symfony/web/app_dev.php ujrzysz pustą stronę WWW, może to świadczyć o tym, że zainstalowana jest zbyt stara wersja PHP. W celu upewnienia się, że zainstalowane oprogramowanie jest odpowiednie, odwiedź adres: http://localhost/Symfony/web/config.php Powinieneś ujrzeć stronę widoczną na rysunku 1.3.
4
Błąd ten występuje w systemie Windows 7, gdy w PHP zainstalowany jest akcelerator APC.
Rozdział 1. ♦ Uruchomienie przykładowego projektu
21
Rysunek 1.3. Strona sprawdzająca, czy zainstalowane oprogramowanie jest odpowiednie
Oczywiście należy usunąć wszelkie błędy zgłaszane przez skrypt widoczny na rysunku 1.3.
Błąd: próba zdalnego dostępu do app_dev.php Jeśli stronę z rysunku 1.2 zechcesz odwiedzić z innego komputera, podając adres serwera, na którym utworzyłeś folder Symfony/, np.: http://192.168.0.5/Symfony/web/app_dev.php http://moj.serwer.example.net/Symfony/web/app_dev.php ujrzysz wówczas komunikat o zakazie dostępu: You are not allowed to access this file...
W celu ominięcia powyższego zabezpieczenia usuń z pliku Symfony/web/app_dev. php kod: if (!in_array(@$_SERVER['REMOTE_ADDR'], array( '127.0.0.1', '::1', ))) { header('HTTP/1.0 403 Forbidden'); exit('You are not allowed to access this file. Check '.basename(__FILE__).' for ´more information.'); }
Część I ♦ Tworzenie prostych stron WWW
22
Błąd: nieaktualne pliki w folderze app/cache/ Po odwiedzeniu adresu: http://localhost/Symfony/web/app_dev.php w folderze Symfony/app/cache/ tworzone są foldery i pliki zawierające przetworzone informacje o konfiguracji projektu. W niektórych przypadkach (np. wtedy, gdy przeniesiesz projekt do innego folderu) zawartość folderu Symfony/app/cache/ może być nieaktualna. W celu wyczyszczenia pamięci podręcznej projektu usuń wszystkie pliki i foldery znajdujące się w folderze Symfony/app/cache/.
Błąd: akcelerator nie odświeża ścieżek Jeśli korzystasz z akceleratora APC, to po przeniesieniu projektu do innego folderu możesz napotkać problemy polegające na odwoływaniu się przez projekt do nieistniejących plików oraz folderów. Problem ten wyeliminujesz, restartując serwer Apache. Jeśli w adresie: http://localhost/hello-world/web/app_dev.php spróbujesz pominąć nazwę pliku app_dev.php: http://localhost/hello-world/web/ ujrzysz wówczas stronę z tekstem: Oops! An Error Occurred The server returned a "404 Not Found".
Nie świadczy to o żadnym błędzie. Wszystko przebiega poprawnie. Adres: http://localhost/hello-world/web/app_dev.php uruchamia aplikację w środowisku deweloperskim, w którym strona główna wygląda tak jak na rysunku 1.2. Adres: http://localhost/hello-world/web/ uruchamia natomiast aplikację w środowisku produkcyjnym. Ponieważ w tym środowisku aplikacja jest pusta, tj. nie zawiera żadnej strony WWW, wyświetlany jest komunikat o nieodnalezionej stronie WWW: 404 Not Found.
Podsumowanie Uruchamiając przykładową aplikację, poznaliśmy rolę, jaką odgrywają pliki i foldery widoczne na rysunku 1.4.
Rozdział 1. ♦ Uruchomienie przykładowego projektu
23
Rysunek 1.4. Pliki i foldery poznane podczas uruchamiania przykładowej aplikacji
Symfony 2 jest rozpowszechniane w postaci dwóch dystrybucji: with vendors, without vendors.
Dystrybucja without vendors nie zawiera folderu vendor/, w którym znajdują się rozmaite pakiety konieczne do uruchomienia aplikacji. Dlatego naukę rozpoczynamy od dystrybucji with vendors. Pamiętaj o roli, jaką odgrywają: folder app/cache/ oraz skrypty:
web/config.php web/app.php web/app_dev.php W folderze app/cache/ zapisywana jest zawartość pamięci podręcznej aplikacji. W celu odświeżenia pamięci podręcznej możesz usunąć zawartość tego folderu. Podane trzy skrypty PHP mają adresy: http://localhost/Symfony/web/config.php http://localhost/Symfony/web/app.php http://localhost/Symfony/web/app_dev.php Pierwszy z nich — config.php — sprawdza, czy zainstalowane oprogramowanie spełnia warunki Symfony 2. Skrypt app_dev.php wyświetla przykładową aplikację widoczną na rysunku 1.2. Skrypt app.php powoduje wyświetlenie informacji o błędzie.
24
Część I ♦ Tworzenie prostych stron WWW
Rozdział 2.
Hello, world! Pierwsza aplikacja, którą wykonamy, ma Cię zapoznać z procesem tworzenia i uruchamiania projektu oraz ze strukturą aplikacji. Oprogramowanie Symfony 2 jest zaimplementowane obiektowo z wykorzystaniem przestrzeni nazw (ang. namespace). Aplikacja tworzona w Symfony 2 jest podzielona na: pakiety (ang. bundle), kontrolery (ang. controller), akcje (ang. action), widoki (ang. view).
Przestrzenie nazw Przestrzenie nazw umożliwiają stosowanie wieloczłonowych nazw klas. Dzięki temu nazwy klas zawartych w aplikacji tworzą strukturę drzewa. Na przykład w Symfony 2 występują klasy o nazwach: Symfony\Component\Finder\Finder Symfony\Component\DomCrawler\Crawler Symfony\Component\ClassLoader\UniversalClassLoader
Przestrzenie nazw rozwiązują dwa istotne problemy dotyczące nazewnictwa klas w dużych projektach: Gwarantują niezależność nazw klas tworzonych przez grupy programistów. Umożliwiają stosowanie skróconych nazw.
Dzięki temu wewnątrz własnej aplikacji możemy utworzyć klasę o nazwie Lorem, nie przejmując się tym, czy w innym miejscu aplikacji istnieje klasa o identycznej nazwie. Przestrzenie nazw tworzymy, umieszczając klasy w osobnych folderach i dołączając deklarację namespace.
Część I ♦ Tworzenie prostych stron WWW
26
W celu utworzenia w aplikacji klasy o pełnej nazwie: Lorem\Ipsum\Dolor\Sit.php
należy utworzyć foldery Lorem, Ipsum i Dolor oraz umieścić w nich plik Sit.php: Lorem\Ipsum\Dolor\Sit.php
Plik Sit.php rozpoczynamy od deklaracji: namespace Lorem\Ipsum\Dolor; class Sit { }
Pełną nazwą klasy jest: Lorem\Ipsum\Dolor\Sit
W celu utworzenia obiektu klasy Sit możesz wykonać instrukcję: new Lorem\Ipsum\Dolor\Sit();
W celu skrócenia powyższego zapisu w dowolnym pliku aplikacji możesz dodać instrukcję: use Lorem\Ipsum\Dolor\Sit;
dzięki czemu tworzenie obiektu klasy Sit przyjmie krótszą formę: new Sit();
Pakiet Pakiety są niezależnymi fragmentami aplikacji. Każdy z pakietów może być wykorzystywany w wielu różnych aplikacjach. Cały pakiet jest umieszczony wewnątrz jednego folderu i może zawierać kontrolery, akcje, widoki, pliki konfiguracyjne, klasy pomocnicze oraz zasoby takie jak style CSS, obrazy czy skrypty JavaScript. Pojedynczy pakiet może stanowić małą cząstkę aplikacji, np.: KnpMarkdownBundle — zestaw klas do interpretacji plików w języku
Markdown; KnpPaginatorBundle — zestaw klas ułatwiających wykonywanie stronicowania (odpowiednik klas Pager z Symfony 1.4 oraz Zend
Framework). Przykładami pakietów nieco większych są: DoctrineFixturesBundle — obsługa plików fixtures.yml, które ułatwiają
wypełnianie bazy danych;
Rozdział 2. ♦ Hello, world!
27
DoctrineExtensionsBundle — obsługa zachowań sluggable, timestampable
itd. dla obiektów Doctrine; DoctrineMigrationsBundle — obsługa migracji baz danych.
Dużymi fragmentami aplikacji są pakiety: SonataAdminBundle — panel administracyjny CRUD; FOSUserBundle — administracja kontami użytkowników (m.in. rejestracja
z potwierdzaniem e-mailem, resetowanie i zmiana hasła); SonataPageBundle — system CMS; FOSCommentBundle — obsługa wielowątkowych komentarzy.
Wspólną cechą wszystkich pakietów jest ich niezależność od konkretnej aplikacji. Celem tworzenia pakietów jest ułatwienie ponownego wykorzystania fragmentu projektu. Nazewnictwo pakietów jest dwuczłonowe. Pierwszy człon nazwy pakietu możemy traktować jako nazwę autora pakietu, a drugi — jako nazwę samego pakietu. Pakiet Symfony 2 jest odpowiednikiem wtyczki z Symfony 1.4.
Kontroler i akcja W Symfony 2 kontroler odpowiada za przetworzenie żądania HTTP i wygenerowanie odpowiedzi. Wprawdzie kontrolerem może być zarówno metoda klasy, jak i zwykła funkcja, jednak w przykładach omawianych w dalszej części podręcznika w roli kontrolera będziemy stosowali wyłącznie metody klasy. Na przykład w projekcie omawianym w bieżącym rozdziale wystąpi klasa Default ´Controller, a w niej metoda: public function indexAction() { }
Dla ułatwienia będę stosował konwencję nazewniczą z frameworków Symfony 1.4 oraz Zend Framework. Kontrolerem będę nazywał klasę (np. DefaultController), zaś akcją — metodę (np. indexAction()). Unikniemy wówczas dwuznaczności. Dokumentacja Symfony 2 stosuje termin „kontroler” w odniesieniu do zarówno klasy (np. DefaultController), jak i samej metody (np. indexAction()).
Część I ♦ Tworzenie prostych stron WWW
28
Widok Widoki to pliki, które zawierają kod HTML oraz specjalne instrukcje umieszczające w kodzie HTML wartości zmiennych. W Symfony 2 domyślnym językiem przetwarzania widoków jest Twig. Pliki widoków mają podwójne rozszerzenie .html.twig.
Przykład 2.1. Hello, world! Wykorzystując oprogramowanie Symfony 2, wykonaj aplikację, która będzie prezentowała stronę WWW z tekstem Hello, world!. Zadanie rozwiąż w taki sposób, by adres strony kończył się napisem /hello-world.html. Jeśli podczas wykonywania przykładu ujrzysz białą stronę, pamiętaj, że pierwszym krokiem do usunięcia powstałego błędu jest wyczyszczenie pamięci podręcznej i odświeżenie strony. W tym celu najlepiej wyczyścić zawartość folderu app/cache/. Komenda: php app/console cache:clear
często zawodzi. Drugim krokiem, który stosuję w przypadku błędnego działania akceleratora APC, jest restart serwera Apache. Jeśli i to nie pomaga, sprawdzam, jakie informacje zwraca skrypt web/config.php.
ROZWIĄZANIE Krok 1. Utwórz nowy projekt Symfony 2 W folderze przeznaczonym na aplikacje WWW1 utwórz folder hello-world/. Do folderu tego wypakuj zawartość archiwum Symfony_Standard_Vendors_2.0.X.zip. Po wykonaniu tej operacji zawartość folderu hello-world/ powinna być taka jak na rysunku 2.1.
Krok 2. Usuń pakiet demo Plik Symfony_Standard_Vendors_2.0.X.zip zawiera pakiet demonstracyjny, który nie jest konieczny do tworzenia nowych aplikacji. W celu usunięcia pakietu demo: Usuń folder hello-world/src/Acme/. W pliku hello-world/app/AppKernel.php usuń wpis: $bundles[] = new Acme\DemoBundle\AcmeDemoBundle();
W pliku hello-world/app/config/routing_dev.php usuń wpisy przedstawione
na listingu 2.1. Usuń folder hello-world/web/bundles/acmedemo/. 1
Procedura instalacji oprogramowania jest przedstawiona w dodatku A. Jeśli przygotowałeś stanowisko pracy zgodnie z podanym opisem, to tym folderem jest C:\xampp\htdocs\.
Rozdział 2. ♦ Hello, world!
29
Rysunek 2.1. Foldery i pliki projektu Hello, World!
Listing 2.1. Reguły, które należy usunąć z pliku hello-world/app/config/routing_dev.php _welcome: pattern: / defaults: { _controller: AcmeDemoBundle:Welcome:index } _demo_secured: resource: "@AcmeDemoBundle/Controller/SecuredController.php" type: annotation _demo: resource: "@AcmeDemoBundle/Controller/DemoController.php" type: annotation prefix: /demo
Krok 3. Tworzenie pakietu Pakiety tworzymy, uruchamiając w wierszu poleceń komendę: php app/console generate:bundle
Powyższa komenda będzie działała poprawnie wyłącznie wtedy, gdy program php.exe jest dostępny w ścieżkach poszukiwań. Należy także pamiętać, że php.exe uruchamiane wsadowo może mieć inną konfigurację niż PHP uruchamiane protokołem HTTP. Do sprawdzenia poprawności instalacji PHP w wierszu poleceń służy skrypt app/check.php, który uruchamiamy poleceniem: php app/check.php
Procedura instalacji PHP w wierszu poleceń jest szczegółowo opisana w dodatku A.
Krok 3.1. Utwórz nowy pakiet My/HelloworldBundle Uruchom wiersz poleceń i komendami cd przejdź do folderu hello-world/. Następnie wydaj komendę: php app/console generate:bundle
która wygeneruje nowy pakiet (ang. bundle) wewnątrz projektu. Po wydaniu komendy w odpowiedzi na monit: Bundle namespace:
Część I ♦ Tworzenie prostych stron WWW
30
wprowadź nazwę pakietu: My/HelloworldBundle
Nazwa pakietu jest dwuczłonowa. Pierwszy człon może być traktowany jako oznaczenie autora pakietu. Nazwa: My/HelloworldBundle
spowoduje utworzenie w folderze src/ folderów: hello-world/ src/ My/ HelloworldBundle/
Cały kod tworzonego pakietu zostanie umieszczony wewnątrz folderu: hello-world/src/My/HelloworldBundle/. Nazwa pakietu musi się kończyć przyrostkiem Bundle. Poprawnymi nazwami pakietów są: Gajdaw/HelloworldBundle GW/HelloBundle Gajda/HelloWorldBundle
Komenda app/console generate:bundle działa w sposób interaktywny i umożliwia dostosowanie kilku parametrów generowanego pakietu. Możemy: zmienić folder, w którym zostanie umieszczony pakiet; ustalić sposób konfiguracji pakietu (YML, XML, PHP lub adnotacje2); włączyć tworzenie kompletnej struktury pakietu (po włączeniu tej opcji
wygenerowane zostaną m.in. puste foldery public/css/ oraz public/images/ przeznaczone na style CSS oraz obrazy); dołączyć nowy pakiet do konfiguracji aplikacji; zmodyfikować reguły routingu adresów URL tak, by uwzględniony został
nowo tworzony pakiet. Interaktywny generator podpowiada domyślne wartości opcji: Bundle name [MyHelloworldBundle]: Target directory [...\hello-world/src]: Configuration format (yml, xml, php, or annotation) [annotation]: Do you want to generate the whole directory structure [no]? Do you confirm generation [yes]? Confirm automatic update of your Kernel [yes]? Confirm automatic update of the Routing [yes]?
2
Adnotacje są specjalnymi komentarzami umieszczanymi w kodzie PHP.
Rozdział 2. ♦ Hello, world!
31
Na wszystkie powyższe pytania możemy odpowiedzieć, naciskając przycisk Enter. Opcje przyjmą wówczas wartości podane w nawiasach kwadratowych. W celu wygenerowania nowego pakietu w sposób wsadowy (tj. bez trybu interaktywnego) wydaj komendę app/console generate:bundle w sposób następujący: php app/console generate:bundle --namespace=My/HelloworldBundle --dir=src ´--no-interaction
Wymaganymi parametrami polecenia generate:bundle są: --namespace — parametr ustalający nazwę pakietu; --dir — parametr ustalający położenie generowanego pakietu.
Ostatnia z opcji, --no-interaction, wyłącza tryb interaktywny.
Krok 3.2. Sprawdź strukturę wygenerowanego pakietu Po wydaniu komendy app/console generate:bundle w folderze hello-world/src/ utworzony zostanie pakiet, którego foldery i pliki przedstawiono na rysunku 2.2. Rysunek 2.2. Foldery i pliki utworzone po wydaniu komendy app/console generate:bundle
Bezpośrednio w folderze hello-world/src/ znajduje się plik .htaccess zawierający instrukcję: deny from all
Blokuje on dostęp do zawartości folderu hello-world/src/ za pomocą protokołu HTTP3. Pakiet hello-world/src/My/HelloworldBundle/ zawiera następujące foldery: 3
Innymi słowy do folderu hello-world/src/ nie da się zajrzeć za pomocą przeglądarki.
Część I ♦ Tworzenie prostych stron WWW
32
Controller/ — folder przeznaczony na kontrolery; DependencyInjection/ — folder konfigurujący zależności pomiędzy
obiektami; Resources/ — folder zawierający zasoby pakietu (m.in. szablony, style CSS
oraz obrazy); Tests/ — folder przeznaczony na testy jednostkowe.
Jeśli na pytanie: Do you want to generate the whole directory structure [no]?
odpowiesz: yes
wówczas w folderze Resources/ wygenerowane zostaną dodatkowo foldery i pliki widoczne na rysunku 2.3. Folder doc/ jest przeznaczony na dokumentację, public/ — na style CSS, skrypty JavaScript oraz obrazy, a translations/ — na pliki tłumaczeń. Rysunek 2.3. Kompletna struktura zasobów z folderu Resources/
Krok 3.3. Sprawdź zawartość pliku app/AppKernel.php Opcja konfiguracyjna: Confirm automatic update of your Kernel [yes]?
powoduje włączenie nowo tworzonego pakietu w konfiguracji aplikacji. W pliku hello-world/app/AppKernel.php w tablicy $bundles utworzony zostanie obiekt klasy MyHelloworldBundle: $bundles = array( ... new My\HelloworldBundle\MyHelloworldBundle(), );
Plik AppKernel.php jest przedstawiony na listingu 2.2.
Rozdział 2. ♦ Hello, world!
33
Listing 2.2. Plik AppKernel.php
MyHelloworldBundle:Default:index
5
Adnotacje @Template() omówimy szczegółowo w części poświęconej szablonom Twig.
Część I ♦ Tworzenie prostych stron WWW
46
Format PHP Po wybraniu formatu konfiguracji PHP konfiguracja routingu zostanie zapisana w pliku: src\My\HelloworldBundle\Resources\config\routing.php
w formacie: $entities); } }
Krok 8. Dostosuj widok akcji index Utwórz plik src/My/FrontendBundle/Resources/views/Kontynent/index.html.twig o zawartości takiej jak na listingu 32.16. Listing 32.16. Widok akcji index {% extends "::layout.html.twig" %} {% block content %} Lista wszystkich kontynentów
Część VII ♦ Relacje
356
Title |
---|
{{ novel }} |
Name |
---|
{{ detective }} |
Name |
---|
{{ method }} |
Name | {{ entity }} |
---|