Development

Documentation/pl_PL/book/1.0/02-Exploring-Symfony-s-Code

You must first sign up to be able to contribute.

Version 9 (modified by pawelhenek, 9 years ago)
--

Rozdział 2 - Badamy Symfony

Na pierwszy rzut oka, kod aplikacji bazującej na symfony może wydawać się naprawdę odrzucający. Składa się z wielu katalogów i skryptów, a pliki to mieszanka klas PHP, HTMLa, a nawet obu technologii jednocześnie. Można zobaczyć w nich również odwołania do klas, których nie znajdziemy wśród folderów aplikacji, a stopień zagłębienia katalogów sięga nawet sześciu poziomów. Jednak gdy raz dostrzeżesz powód, dla którego to wszystko wygląda na tak bardzo złożone, zrozumiesz natychmiast, że to tak bardzo naturalne, iż nigdy nie będziesz chciał wymienić struktury aplikacji symfony na żadną inną. Ten rozdział objaśni Ci to początkowo zastraszające uczucie.

Wzorzec MVC

Symfony bazuje na klasycznym webowym wzorcu projektowym znanym jako architektura MVC, która składa się z trzech poziomów:

  • warstwa modelu reprezentuje informacje, na których aplikacja wykonuje operacje - jej logika biznesowa.

  • warstwa widoku przekształca model(informacje) w stronę internetową wygodną do interakcji z użytkownikami.

  • warstwa kontrolera reaguje na akcje użytkownika i zarządza odpowiednie zmiany w warstwie modelu albo widoku.

Rycina 2.1 ilustruje wzorzec MVC.

Architektura MVC oddziela logikę biznesową (model) oraz warstwę prezentacji (widok), skutkując łatwością konserwacji aplikacji. Na przykład jeśli twoja aplikacja powinna działać zarówno na standardowych przeglądarkach oraz urządzeniach przenośnych, potrzebujesz wtedy tylko nowej warstwy widoku; możesz używać nadal pierwotnego kontrolera i modelu. Kontroler pomaga ukryć szczegóły protokołu, którego użyto do wykonania zapytania (HTTP, tryb konsoli, mail, itd.) z modelu i widoku. Model abstrahuje logikę danych, tworząc widok i akcje niezależne od siebie, na przykład typ bazy danych używanej w aplikacji.

[[Image(/images/book/1_0/F0201.png)]]

Warstwy wzorca MVC

By pomóc Ci w dostrzeżeniu zalet wzorca MVC pokażemy jak przerobić prostą aplikację PHP na strukturę zgodną z architekturą MVC. Doskonałym przykładem ku temu będzie aplikacja obsługująca blog internetowy.

Jednolite programowanie

[php]

<?php

// Connecting, selecting database
$link = mysql_connect('localhost', 'myuser', 'mypassword');

mysql_select_db('blog_db', $link);

// Performing SQL query
$result = mysql_query('SELECT date, title FROM post', $link);

?>

<html>
  <head>
    <title>List of Posts</title>
  </head>
  <body>
   <h1>List of Posts</h1>
   <table>
     <tr><th>Date</th><th>Title</th></tr>
<?php
// Printing results in HTML
while ($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
echo "\t<tr>\n";
printf("\t\t<td> %s </td>\n", $row['date']);
printf("\t\t<td> %s </td>\n", $row['title']);
echo "\t</tr>\n";
}
?>
    </table>
  </body>
</html>

<?php

// Closing connection
mysql_close($link);

?>

W pojedynczym pliku wyświetlanie listy wpisów z bazy danych mogłoby wyglądać podobnie do tego jak zaprezentowano na listingu 2-1. Taki kod jest łatwy do napisania, szybki do odpalenia i niemożliwy do utrzymania. Poniżej znajdują się największe problemy związane z tym kodem:

  • Brak sprawdzania błędów (co jeśli zawiedzie połączenie z bazą danych?)

  • HTML i PHP są wymieszane, a nawet wzajemnie przeplatane

  • Kod jest zależny od bazy danych MySQL

Oddzielanie warstwy prezentacyjnej

Wywołania funkcji echo i printf w listingu 2-1 tworzą kod trudny do odczytania. Modyfikowanie kodu HTML w celu poprawy prezentacji jest istną mordęgą przy aktualnej składni. W takim razie kod może zostać rozdzielony na dwie części. Pierwsza z nich to czysty kod PHP z całą logiką biznesową zawartą w skrypcie kontrolera, jak pokazano na listingu 2-2. Kod HTML zawierający składnię podobną do szablonów PHP jest umieszczony w skrypcie widoku, co obrazuje listing 2-3. Dobrą regułą przy decydowaniu co ma zostać wydzielone z warstwy widoku jest pozostawienie w pliku minimalnej ilości kodu PHP, takiej która będzie zrozumiała dla projektanta HTML bez zaawansowanej wiedzy o PHP. Najbardziej powszechnymi wyrażeniami są echo, if/endif, , foreach/endforeach, i to wszystko. Kod nie powinien także zawierać wywołań echo z tagami HTMLa jako argumentami. Cała logika zostanie przeniesiona do skryptu kontrolera, zawierając czysty kod PHP, bez jakiegokolwiek HTMLa. Prawdę mówiąc powinieneś wyobrazić sobie, że ten sam kontroler mógłby zostać ponownie użyty z absolutnie odmienną warstwą prezentacji, możliwe że z plikiem PDF albo XML.

Oddzielanie warstwy manipulacji na danych

Spora część kodu skryptu kontrolera odpowiada za operacje manipulacji na danych. Co jednak gdy potrzebujesz listy postów dla innego kontrolera, powiedzmy że jest to udostępniany na zewnątrz kanał RSS z postami pochodzącymi z naszego bloga. Co jeśli chcesz przechowywać wszystkie zapytania do bazy danych w jednym miejscu, by uniknąć duplikowania kodu? Co jeśli zdecydujesz się na zmiany w warstwie modelu w taki sposób, że tabelę "post" nazywasz "weblog_post"? Co jeśli chcesz zamienić bazę danych MySQL na PostreSQL? Aby to wszystko było możliwe, musimy usunąć kod odpowiedzialny za operacje na danych ze skryptu kontrolera i przenieść go do innego skryptu, zwanego modelem, jak pokazano na listingu 2-4. Ulepszony kontroler został zaprezentowany na listingu 2-5. Kontroler stał się łatwiejszy do odczytania. Teraz jego jedynym zadaniem jest pobieranie danych z modelu i przekazanie ich do warstwy widoku. W bardziej złożonych aplikacjach kontroler obsługuje także żądania, sesję użytkownika, autoryzację itd. Używanie sprecyzowanych nazw funkcji w warstwie modelu sprawia, że komentowanie kodu w kontrolerze jest niepotrzebne. Skrypt modelu jest wydzielony do dostępu do danych i wobec tego może być odpowiednio zorganizowany. Wszystkie parametry niezależne od warstwy danych (jak parametry zapytań) muszą być przekazywane przez kontroler, bez bezpośredniego dostępu z modelu. Funkcje modelu powinny być łatwe do ponownego użycia w innym kontrolerze.

Poza warstwami wzorca MVC

W takim razie prawem rządzącym architekturą MVC jest separacja kodu w trzy warstwy, zgodnie z ich naturalnym przeznaczeniem. Kod logiki danych jest umieszczony w modelu, kod prezentacji w widoku, zaś logika aplikacji w kontrolerze. Inne dodatkowe wzorce projektowe mogą sprawić że kodowanie będzie jeszcze łatwiejsze. Warstwy modelu, widoku i kontrolera mogą być dalej dzielone na mniejsze części.

Abstrakcja bazy danych

Model można rozbić na warstwę dostępu do danych oraz warstwę abstrakcji bazy danych. Tym sposobem funkcje dostępowe danych nie będą używać zapytań z wyrażeniami charakterystycznymi dla konkretnego systemu bazy danych, ale wywołają kilka innych funkcji, które same wykonają odpowiednie zapytania zgodne z danym silnikiem bazy danych. Jeśli zmienisz później swój system bazy danych, tylko warstwa abstrakcji bazy danych będzie wymagała aktualizacji. Przykład specyficzny dla warstwy dostępu do danych w systemie MySQL został zaprezentowany na listingu 2-6, po którym następuje przykład z warstwą abstrakcji bazy danych na listingu 2-7. Możesz sprawdzić, że żadnych funkcji zależnych od silnika bazy danych nie można znaleźć w warstwie dostępu do danych, czyniąc je niezależne od używanego systemu bazodanowego. Dodatkowo funkcje stworzone w warstwie abstrakcji bazy danych mogą zostać ponownie użyte w wielu innych funkcjach modelu, które potrzebują dostępu do bazy danych. Przykłady w listingach 2-6 i 2-7 nadal nie są satysfakcjonujące i wciąż pozostało trochę roboty do wykonania by mieć prawdziwą warstwę abstrakcji bazy danych (oddzielenie kodu SQL przez generator zapytań niezależnych od używanego systemu bazy danych, przenosząc wszystkie funkcje w klasy itd.). Jednak celem tej książki nie jest pokazanie jak napisać taki kod samodzielnie od zera, w rozdziale 8 zobaczysz że symfony bardzo dobrze radzi sobie z dostarczaniem Ci poziomu abstrakcji dla bazy danych.

Elementy widoku

Warstwa widoku może także przynosić korzyści z separacji kodu. Strony internetowe często zawierają podobne elementy w całej aplikacji: nagłówki stron, układ graficzny, stopkę oraz globalną nawigację. Tylko wewnętrzna część strony się zmienia. Dlatego właśnie widok został rozdzielany na układ graficzny oraz szablon. Układ jest najczęściej wspólny dla całej aplikacji, bądź dla jakiejś grupy podstron. Szablon tylko porządkuje zmienne tworząc je dostępne dla kontrolera. Minimalna ilość logiki jest potrzebna by te komponent mogły współpracować ze sobą i tą warstwę logiki nazwiemy widokiem. Zgodnie z tymi zasadami, część widoku przedstawiona na listingu 2-3 może zostać rozdzielona na trzy części, jak to pokazano na listingach 2-8, 2-9, 2-10.

Akcja i Front Controller

W poprzednim przykładzie kontroler nie ma zbyt dużo do roboty, ale w rzeczywistych aplikacjach sieciowych naprawdę ma co robić. Ważną częścią jego zadań jest integracja wszystkich kontrolerów aplikacji. Integracja takich zadań jak obsługa żądań, zapewnienie bezpieczeństwa, ładowanie konfiguracji aplikacji i temu podobna robota. Oto dlaczego kontroler jest często rozdzielany na tzw. front kontroler, który jest unikalny dla całej aplikacji oraz akcji, zawiera on specyficzny kod kontrolera dla pojedynczej strony. Jedną z największych zalet front kontrolera jest oferowanie unikalnego punktu wejścia dla całej aplikacji. Jeśli zdecydujesz się nawet zamknąć dostęp do całej aplikacji potrzebujesz edytować tylko skrypt front kontrolera. W aplikacji bez przedniego kontrolera każdy pojedynczy kontroler musiałby zostać wyłączony.

Orientacja obiektowa

Wszystkie poprzednie przykłady używały programowania proceduralnego. Możliwości obiektowej orientacji nowoczesnych języków programowania sprawia że kodowanie jest jeszcze łatwiejsze, od kiedy obiekty mogą zawierać logikę, dziedziczyć jeden od drugiego oraz dostarczają przejrzysty system nazewnictwa. Implementacja architektury MVC w języku, który nie jest zorientowany obiektowo prowadzi do duplikacji kodu, przestrzeni nazw przez co cały kod jest ciężki do analizy. Orientacja obiektowa pozwala deweloperom na używanie takich pojęć jak obiekt widoku, obiekt kontrolera, klasy modelu i przekształcać wszystkie funkcje z poprzednich przykładów w metody. To konieczne przy używaniu architektury MVC. Jeśli chcesz dowiedzieć się więcej na temat wzorców projektowych dla aplikacji webowych w kontekście obiektowości, przeczytaj książkę "Patterns of Enterprise Application Architecture" napisaną przez Martina Fowlera (Addison-Wesley, ISBN: 0-32112-742-0). Przykłady kodu w jego książce są napisane w Javie, C#, mimo to są zrozumiałem dla deweloperów PHP.

Implementacja wzorca MVC w Symfony

Zatrzymajmy się na chwilę. Jak wiele komponentów potrzebuje nasza aplikacja dla wyświetlania pojedynczej strony z postami bloga? Jak ilustruje rycina 2-2, wydzielamy takie części: - warstwa modelu - abstrakcja bazy danych - dostęp do danych - warstwa widoku - logika widoku - szablon (miejsce na zmienne) - układ graficzny - warstwa kontrolera - przedni kontroler - akcje Całe siedem skryptów do otwierania i modyfikowania, za każdym razem gdy tworzysz nową podstronę. Jednak symfony znacznie to ułatwia. Biorąc to co najlepsze z architektury MVC, symfony implementuje te zadania w taki sposób, że tworzenie aplikacji staje się szybkie i bezbolesne. Przede wszystkim, front kontroler i układ graficzny są powszechne dla wszystkich akcji w Twojej aplikacji. Możesz mieć wiele kontrolerów i układów graficznych, ale potrzebujesz tylko jednego dla każdego. Front kontroler jest czystym logicznie komponentem wzorca MVC i nigdy nie będziesz potrzebować tworzyć własnego, ponieważ symfony stworzy go za Ciebie. Inną dobrą wiadomością jest to, że klasy warstwy danych są także generowane automatycznie, bazując na Twojej strukturze danych. To jest zadanie biblioteki Propel, która dostarcza szkielety klas i generowanie kodu. Jeżeli Propel znajdzie ograniczające go klucze obce albo pola danych, potrafi wykorzystać wtedy specjalne metody akcesora bądź mutatora, które uczynią manipulowanie danymi bułką z masłem. Także warstwa abstrakcji bazy danych jest całkowicie niewidzialna dla Ciebie, ponieważ to zadanie jest dzielone z innym komponentem, zwanym Creole. Jeżeli więc zdecydujesz się na chwilową zmianę silnika bazy danych, nie masz żadnego kodu do dopisania. Musisz zmienić tylko parametry konfiguracyjne. Ostania sprawa dotyczy logiki widoku, który może być łatwo eksportowany jako pojedynczy plik konfiguracyjny, bez żadnych zadań programistycznych. To znaczy, że lista postów opisana w naszym przykładzie mogłaby zawierać tylko trzy pliki by pracować z symfony, jak pokazują listingi 2-11, 2-12 i 2-13. Dodatkowo, nadal potrzebujesz definiować layout, jak pokazano na listingu 2-14, ale będzie on używany wiele razy. I to rzeczywiście wszystko czego potrzebujesz! To jest dokładnie cały kod, wystarczający do wyświetlenia takiej samej strony jak ta, którą pokazaliśmy wcześniej w pojedynczym pliku, na listingu 2-1. Całą resztą (sprawiającą że wszystko to działa razem) są odpowiednie elementy symfony. Jeśli liczysz linie kodu, widzisz że stworzenie listy postów wykorzystując do tego architekturę MVC dostarczaną przez symfony nie wymaga więcej czasu czy kodowania, niż zapisanie odpowiedniego kodu w jednolitym pliku. Jednakże dostarcza to ogromnych korzyści, szczególnie przejrzystej organizacji kodu, użyteczności, elastyczności i innych plusów. Na dodatek masz zgodny kod XHTML, możliwości debugowania, łatwej konfiguracji, abstrahowania bazy danych, użyteczny routing adresów URL, mnogość środowisk i wiele innych narzędzi deweloperskich.

Główne klasy Symfony

Implementacja MVC w symfony wykorzystuje kilka klas, które będziesz całkiem często spotykać w tej książce: - sfController jest kontrolerem klas. On odbiera zapytania i przekazuje je do akcji. - sfRequest magazynuje wszystkie elementy zapytań (parametry, ciasteczka, nagłówki itp.). - sfRespone zawiera nagłówki i zawartość odpowiedzi. Ten obiekt ostatecznie zostaje skonwertowany do odpowiedzi HTML i wysłany do użytkownika - obiekt tła wywołania (odzyskiwany dzięki sfContext::getinstance()) przechowuje referencje do wszystkich obiektów jądra i konfiguracji; jest dostępny zewsząd Powiemy o nim więcej w rozdziale 6. Jak widzisz, wszystkie klasy symfony używają przedrostka sf, tak jak zmienne jądra symfony w szablonach. To powinno zapobiec kolizji nazw z Twoimi własnymi klasami i zmiennymi oraz uczynić klasy frameworka łatwiejszymi do rozpoznania. Wśród standardów kodowania używanych w symfony, notacja UpperCamelCase jest używana przy nazywaniu zmiennych i klas. Istnieją jednak dwa odstępstwa od tej reguły: klasy jądra symfony zaczynają się od sf, co jest notacją lowercase, i zmienne w szablonach używają składni ze znakiem podkreślenia jako separatora.

Organizacja kodu

Teraz znasz już różne komponenty aplikacji symfony, bardzo możliwe że jesteś ciekawy jak są one zorganizowane. Symfony porządkuje kod w strukturę projektu i rozmieszcza pliki projektu w standardowej strukturze drzewa.

Struktura projektu: aplikacje, moduły i akcje

W symfony projekt jest zbiorem usług i operacji dostępnych spod głównej domeny, dzieląc ten sam obiekt modelu. Wewnątrz projektu operacje zostały logicznie pogrupowane w aplikacje. Aplikacja może być uruchomiona niezależnie od innych aplikacji tego samego projektu. W większości przypadków projekt zawiera dwie aplikacje: jedną dla front-office oraz jedną dla back-office, dzielące tą samą bazę danych. Jednak możesz także mieć jeden projekt zawierający wiele podstron, gdzie każda jest osobną aplikacją. Zauważ, że połączenia pomiędzy aplikacjami muszą być mocno sformalizowane. Każda aplikacja jest zbiorem jednego albo kilku modułów. Moduł reprezentuje zwykle stronę bądź kilka podstron o podobnym przeznaczeniu. Na przykład możesz mieć moduły „dom”, „artykuły”, „pomoc”, „koszyk na zakupy”, „konto”, itp. Moduły obsługują akcje, które reprezentują różne działania wykonywane w module. Na przykład moduł „koszyka na zakupy” może obsługiwać dodawanie, pokazywanie oraz aktualizowanie listy zakupów. Ogólnie rzecz biorąc, akcje mogą być opisywane przez czasownik. Obsługa akcji jest prawie jak obsługa stron w klasycznej aplikacji webowej, pomimo tego iż dwie akcje mogą skutkować taką samą stroną wynikową (przykładowo dodanie komentarza do skrzynki blogowej skutkuje przeładowaniem i wyświetleniem listy komentarzy, już z nowo dodanym). Pomimo tego przedstawienia tak wielu zagadnień potrzebnych do rozpoczęcia projektu, bardzo łatwo pogrupować wszystkie akcje w pojedynczy moduł, po to aby struktura plików mogła być łatwo utrzymana. Kiedy aplikacja obsługuje wiele złożonych zadań, to czas by zorganizować akcje w odseparowane moduły. Jak wspomniano w rozdziale 1, przepisywanie kodu w celu ulepszenia jego struktury i czytelności (przy zachowaniu jego sposobu działania) zostało nazwane refaktoringiem, będziesz to również robić gdy będziesz stosować się do reguł RAD. Rycina 2-3 przedstawia przykład kodu uporządkowanego dla projektu bloga sieciowego, w strukturze projekt/aplikacja/moduł/akcja. Bądź jednak świadomy, że aktualna drzewiasta struktura projektu będzie różnić się od układu pokazanym na rysunku.

Struktura plików

Generalnie wszystkie projekty webowe mają podobne komponenty, takie jak: - bazy danych, np. PostgreSQL lub MySQL - elementy statyczne (HTML, obrazy, pliki javascript, arkusze stylów, itd.) - pliki wgrywane na serwer przez użytkowników bądź administratorów - biblioteki i klasy PHP - inne biblioteki (w innych językach) - partie plików (skryptów do odpalenia z linii poleceń lub przez crona) - logi aplikacji - pliki konfiguracyjne By wszystkie te elementy pogrupować w logiczny sposób symfony dostarcza standardowej struktury drzewa, zgodnej z wybraną architekturą (wzorzec MVC i grupowanie projekt/aplikacja/moduł). Taka struktura drzewa jest automatycznie tworzona gdy inicjalizujesz każdy projekt, aplikację lub moduł. Oczywiście możesz to dowolnie dopasować, przeorganizować pliki i katalogi jak Ci wygodnie albo do wymagań klienta.

Struktura plików źródłowych

Oto katalogi, które można znaleźć w głównym folderze projektu symfony: apps/ - zawiera po jednym katalogu dla każdej aplikacji projektu (zwykle, frontend and backend for the front and back office) batch/ - zawiera skrypty php wywoływane z linii poleceń bądź przez program cyklicznie wywołujący skrypty by wykonywać je seriami cache/ - przechowuje skeszowaną wersję konfiguracji, i (jeśli uaktywniono opcję) skeczowane wersje akcji i szablonów projektu. Mechanizm keszowania (szczegóły w 12 rozdziale) używa tych plików do przyspieszenia odpowiedzi serwera na zapytania. Każda aplikacja posiada tutaj swoje podkatalogi, zawierające przetworzony kod PHP i HTML. config/ - przetrzymuje najważniejsze konfiguracje aplikacji data/ - możesz tutaj przechowywać pliki projektu, takie jak schematy bazy danych, pliki SQL tworzące tabele albo jakiekolwiek zapytania bazy danych. doc/ - przechowuje dokumentację projektu, zawierając twoją własną dokumentację oraz generowaną przez PHPDoc lib/ - wydzielony dla obcych klas i bibliotek. Możesz tutaj dodawać kod, który musisz dzielić w swojej aplikacji. Podkatalog model/ gromadzi warstwę modelu projektu (opisane w 8 rozdziale). log/ - gromadzi przydatne pliki logów wygenerowane bezpośrednio przez symfony. Może także przechowywać pliki logów web serwera, bazy danych, bądź innej części projektu. Symfony tworzy jeden plik log dla każdej aplikacji lub środowiska (szczegóły w rozdziale 16) pluings/ - składuje pluginy zainstalowane w aplikacji (omówione w rozdziale 17) test/ - zawiera testy jednostkowe i funkcjonalne napisane w PHP i kompatybilne z testowym frameworkiem symfony (wyjaśnione w rozdziale 15). Podczas instalacji projektu, symfony automatycznie dodaje fragmenty z kilkoma podstawowymi testami. web/ - główny katalog serwera sieciowego

Struktura plików aplikacji

Drzewo struktury wszystkich podkatalogów aplikacji jest takie same: ; config/ - przetrzymuje pokaźny zbiór plików konfiguracyjnych YAML. Tutaj znajduje się spora część konfiguracji aplikacji, obok domyślnych parametrów, które można znaleźć we frameworku. Zauważ że domyślne parametry mogą ciągle być tutaj przesłaniane jeśli tego potrzebujesz. Nauczysz się więcej o konfiguracji aplikacji w rozdziale 5. i18n/ - zawiera pliki używane do internacjonalizacji aplikacji – przeważnie tłumaczenia plików interfejsu ( rozdział 13 jak radzić sobie z internacjonalizacją ). Możesz pomijać ten katalog jeśli wykorzystujesz bazę danych przy internacjonalizacji. lib/ - przechowuje klasy i biblioteki specyficzne dla danej aplikacji modules/ - gromadzi wszystkie moduły, które zawierając się we własnościach aplikacji templates/ - lista globalnych szablonów aplikacji – te które są współdzielone przez wszystkie moduły. Domyślnie zawiera plik layout.php, który jest głównym szablonem w którym moduły szablonów zostają dołączone. Katalogi i18n/, lib/ i modules/ są puste dla nowych aplikacji. Klasy aplikacji nie potrafią uzyskać dostępu do metod i właściwości innych aplikacji tego samego projektu. Zauważ także iż linki pomiędzy dwoma aplikacjami tego samego projektu muszą być w formacie adresów bezwzględnych. Szczególnie musisz pamiętać o tym ograniczeniu podczas rozpoczynania projektu, gdy będziesz myśleć na jakie aplikacje podzielić projekt.

Struktura plików modułu

Każda aplikacja zawiera kilka lub więcej modułów. Zaś każdy moduł swój własny podkatalog w katalogu modules/, jego nazwa zostaje wybrana w czasie rozpoczynania projektu. Oto typowa struktura drzewa dla modułu: actions/ - ogólnie zawiera pojedyncze pliki klas nazywane klasa.class.php, w których przechowujesz wszystkie akcje modułu. Możesz pisać także różne akcje modułu w osobnych plikach. config/ - może zawierać dowolne pliki konfiguracyjne z parametrami charakterystycznymi dla modułu. lib/ - magazynuje klasy i biblioteki specyficzne dla modułu. templates/ - zawiera szablony odpowiednie dla akcji modułu. Domyślny szablon nazwany indexSuccess.php, został stworzony podczas instalacji modułu. validate/ - przeznaczony dla plików konfiguracyjnych używanych do walidacji formularzy (omawiane w rozdziale 10) Katalogi config/, lib/ oraz validate/ są puste dla nowego modułu

Struktura plików sieciowych

Tutaj jest kilka istotnych ograniczeń dla katalogu web, który jest katalogiem z publicznym dostępem do plików. Poniższych kilka podstawowych konwencji nazewniczych zapewni domyślne zachowania i użyteczne skróty w szablonach. Oto przykład struktury katalogu symfony Umownie pliki statyczne są wydzielone do katalogów takich jak w tabeli 2-4. css/ - zawiera pliki arkuszy stylów z rozszerzeniami .css images/ - zawiera obrazy w formatach .jpg, .png lub .gif. js/ - przetrzymuje skrypty javascript w formacie .js uploads/ - musi przechowywać pliki wgrywane przez użytkownika. Pomimo tego że katalog web zawiera obrazki, ten jest odrębny od obrazków z katalogu images/ po to aby synchronizacja rozwoju i pracy serwera nie wpływały na wgrywane pliki. Pomimo iż jest wysoce zalecane utrzymywanie standardowej struktury drzewa, możliwe jest modyfikowanie jej dla własnych potrzeb, takich jak umożliwienie uruchamiania projektu na serwerze z odmiennymi zasadami tworzenia struktury katalogów i konwencji kodowania. Zajrzyj do rozdziału 19 po więcej informacji na temat modyfikowania struktury plików

Narzędzia

Kilka technik jest wielokrotnie używanych w symfony, będziesz je spotykać całkiem często w tej książce i w swoich projektach. Mowa o uchwytach parametrów, stałych i automatycznego ładowania klas.

Uchwyty parametrów

Wiele klas symfony zawiera tzw. uchwyty parametrów. Jest to wygodny sposób do zachowywania paramerów w pamięci za pomocą metod get i set. Na przykład klasa sfResponse przechowuje parametry, które możesz otrzymać poprzez wywołanie metody getParameterHolder(). Każdy uchwyt parametrów gromadzie je w ten sam sposób, jak pokazano na listingu 2-15. Wiele klas używa tych uchwytów dostarczając metod pośredniczących by skrócić kod potrzebny do operacji ustawiania i pobierania. Obiekt sfRespone jest tego przykładem, możesz więc zrobić to samo co na listingu 2-15 poprzez instrukcje takie jak na listingu 2-16. Funkcja zwracająca parametry akceptuje domyślną wartość jako drugi argument. To dostarcza użytecznego mechanizmu zwrotnego, który jest znacznie bardziej treściwy aniżeli wyrażenia warunkowe. Zobacz listing 2-17. Uchwyty parametrów wspierają nawet przestrzenie nazw. Jeśli określisz trzeci argument do funkcji ustawiającej bądź pobierającej zostanie on użyty jako przestrzeń nazw i parametr zostanie zdefiniowany razem z łącznie z tą przestrzenią. Listing 2-18 pokazuje przykład. Oczywiście możesz dodawać uchwyty parametrów do własnych klas wykorzystując ich dogodną składnię. Listing 2-19 pokazuje jak definiować klasy z uchwytami.

Stałe

O dziwo w symfony możesz znaleźć kilka istotnych stałych. A to dlatego że stałe w PHP mają główną wadę: nie możesz zmienić ich raz zdefiniowanych wartości. Tak więc symfony używa własnego obiektu konfiguracyjnego, zwanym sfConfig który wymienia stałe. Dostarcza on również statycznych metod dzięki którym masz dostęp do parametrów zewsząd. Listing 2-20 pokazuje użycie metod klasy sfConfig. Metody sfConfig wspierają domyślne wartości i możesz wywoływać metodę sfConfig::set() więcej niż raz na jednym parametrze by zmienić jego wartość. Rozdział 5 omawia szczegółowo klasę sfConfig.

Autoładowanie klas

Klasycznie, gdy używasz metod klasy albo tworzysz obiekt w PHP musisz najpierw dołączyć definicję klasy. Jednak w dużych projektach z wieloma klasami i zagłębioną strukturą katalogów, zapamiętanie śladów wszystkich plików klas do dołączania i ich ścieżek zabiera trochę czasu. Dostarczając funkcję _autoload() (albo funkcję splautoload_register() ) symfony sprawia że używanie include jest niepotrzebne i możesz pisać wprost: Wtedy symfony będzie szukać definicji klasy MyClass we wszystkich plikach kończących się na php w jednym z projektowych katalogów lib/. Jeżeli znajdzie definicję klasy, zostanie ona dołączona automatycznie. Jeśli więc przechowuje swoje klasy w katalogu lib/, nie potrzebujesz więcej dołączać klas. Oto dlaczego projekty symfony zwykle nie zawierają wywołań include lub require.

Dla większej wydajności autoładowanie symfony skanuje listę katalogów (zdefiniowaną w wewnętrznym pliku konfiguracyjnym) podczas pierwszego zapytania. Wtedy rejestruje wszystkie klasy i katalogi je zawierające i przechowuje plik/klasę zgodną z formatem plikiu PHP jako tablicę skojarzoną. Tym sposobem przyszłe wywołania nie będą już wymagały kolejnych przeszukiwań katalogów. To też tłumaczy dlaczego musisz czyścić pamięć każdego razu gdy dodasz albo zmienisz pliki z klasami w swoim projekcie, wywołując komendę clear-cache. Więcej na temat pamięci cache nauczysz się w rozdziale 12, a o autoładowaniu w 19.

Podsumowanie

Używanie frameworka MVC zmusza Cię do dzielenia i organizowania kodu według konwencji frameworka. Kod prezentacji wędruje do widoku, manipulacji danymi do modelu, zaś logika manipulacji zapytaniami do kontrolera. To sprawia, że wzorzec MVC jest zarówno pomocny, jak i całkiem wymagający. Symfony jest frameworkiem napisanym w PHP5. Jego struktura została zaprojektowana do czerpania tego co najlepsze ze schematu MVC, ale z jednoczesną łatwością użycia. Dzięki dzięki jego uniwersalności i możliwościom konfiguracji , symfony jest używane przy projektach aplikacji internetowych. Teraz rozumiesz zasadnicze założenia symfony, jesteś także prawie gotowy do rozpoczęcia swojej pierwszej aplikacji. Jednak najpierw musimy zainstalować symfony i uruchomić je na twoim serwerze.