Development

Documentation/pl_PL/book/1.0/04-The-Basics-of-Page-Creation

You must first sign up to be able to contribute.

Version 45 (modified by kwiateusz, 10 years ago)
--

Rozdział 4 - Podstawy tworzenia stron

Ciekawe, pierwszą rzeczą jaką robią programiści podczas nauki nowego języka albo frameworka jest wyświetlanie na ekranie napisu "Witaj świecie!". Dziwnie jest myśleć, że komputer jest czymś co może witać cały świat. Ale Symfony nie jest głupsze niż inne programy, a dowodem na to jest! że możesz stworzyć stronę z napisem "Witaj, (Twoje imię tutaj)"!

Ten rozdział nauczy Cię jak stworzyć moduł, który jest strukturalnym elementem grupującym strony. Dowiesz się także jak stworzyć stronę, która dzieli się na akcję i szablon, czego wymaga wzorzec MVC. Linki i formularze to podstawowe formy interakcji na www. Zobaczysz jak umieścić je w szablonie i operować nimi w akcji.

Tworzenie szkieletu modułu

Jak wyjaśnił rozdział nr 2, Symfony grupuje strony w moduły. Przed stworzeniem strony, musisz stworzyć moduł, który jest początkowo pustą skorupką ze strukturą plików.

Linia komend Symfony automatyzuje tworzenie modułów. Musisz tylko wywołać zadanie 'inti-module' z nazwą aplikacji i nazwą modułu jako argumentami. W poprzednim rozdziale stworzyłeś aplikację o nazwie 'myapp'. Aby dodać moduł 'mymodule' do aplikacji, wprowadź następujące komendy:

> cd ~/myproject
> symfony init-module myapp mymodule

>> dir+      ~/myproject/apps/myapp/modules/mymodule
>> dir+      ~/myproject/apps/myapp/modules/mymodule/actions
>> file+     ~/myproject/apps/myapp/modules/mymodule/actions/actions.class.php
>> dir+      ~/myproject/apps/myapp/modules/mymodule/config
>> dir+      ~/myproject/apps/myapp/modules/mymodule/lib
>> dir+      ~/myproject/apps/myapp/modules/mymodule/templates
>> file+     ~/myproject/apps/myapp/modules/mymodule/templates/indexSuccess.php
>> dir+      ~/myproject/apps/myapp/modules/mymodule/validate
>> file+     ~/myproject/test/functional/myapp/mymoduleActionsTest.php
>> tokens    ~/myproject/test/functional/myapp/mymoduleActionsTest.php
>> tokens    ~/myproject/apps/myapp/modules/mymodule/actions/actions.class.php
>> tokens    ~/myproject/apps/myapp/modules/mymodule/templates/indexSuccess.php

To polecenie tworzy tylko trzy pliki. Jeden w folderze 'test/' jest związany z testami, nie musisz się nim przejmować przed rozdziałem nr 15. Plik 'actions.class.php' (pokazany na listingu 4-1) wysyła do podstawowego modułu stronę gratulacyjną. Plik 'templates/indexSuccess.php' jest na razie pusty.

Listing 4-1 - Domyślna wygenerowana akcja, plik actions/actions.class.php

[php]
<?php

class mymoduleActions extends sfActions
{
  public function executeIndex()
  {
    $this->forward('default', 'module');
  }
}

NOTE Jeżeli patrzysz na aktualny plik 'actions.class.php', możesz znaleźć w nim kilka innych linii, zawierających komentarze. Symfony zachęca używania komentarzy do dokumentowania Twoich projektów i przygotowywania każdego pliku z klasą do kompatybilności z narzędziem phpDocumentator

Dla każdego nowego modułu, Symfony tworzy podstawową akcję - 'index'. Jest ona wkomponowana jako metoda o nazwie 'executeIndex'. Natomiast plik z szablonem nosi nazwę 'indexSuccess.php'. Znaczenie prefixu 'execute' i suffixu 'Success' zostanie wytłumaczone w Rozdziałach nr 6 i 7. Teraz możesz zwrócić uwagę, że nazywanie jest pewną konwencją. Możesz zobaczyć tę stronę (pokazaną na obrazie 4-1) pod adresem URL:

http://localhost/myapp_dev.php/mymodule/index

Domyślna akcja 'index' nie będzie używana w tym rozdziale, więc możesz usunąć metodę 'executeIndex()' z pliku 'actions.class.php' oraz usunąć plik 'indexSuccess.php' z folderu 'templates/'

NOTE Symfony oferuje inne drogi do inicjacji modułów niż z lini poleceń. Jedna z nich to stworzenie folderów i plików samodzielnie. W wielu przypadkach, akcje i szablony modułu manipulują danymi z tabel. Konieczne jest tworzenie, odczytywanie, aktualizowanie i usuwanie rekordów z tabel, w większości przypadków operacje są takie same. Symfony dostarcza Ci mechanizm zwany 'scaffolding', który wygeneruje ten kod za Ciebie! Odsyłam do rozdziału nr 14 po więcej informacji o tej technologi.

Obraz 4-1 - Domyślna wygenerowana strona (index)

Domyślna wygenerowana strona (index)

Dodawanie strony

W Symfony, logika strony jest umieszczona w akcjach, a warstwa prezentacyjna w szablonach. Strony bez logiki (wciąż) wymagają pustej akcji.

Dodawanie akcji

Strona typu "Witaj świecie!" będzie dostępna przez akcję 'myAction'. Aby ją stworzyć, po prostu dodaj metodę 'executeMyAction' w klasie 'mymoduleAction', tak jak pokazano na listingu 4-2.

Listing 4-2 - Dodawanie akcji jest dodawaniem metody do klasy akcji

[php]
<?php

class mymoduleActions extends sfActions
{
  public function executeMyAction()
  {
  }
}

Nazwa akcji wygląda zawsze tak: 'executeXxx()', gdzie druga część nazwy jest nazwą akcji z pierwszą dużą literą.

Teraz, jeżeli przejdziesz pod adres:

http://localhost/myapp_dev.php/mymodule/myAction

Symfony ostrzeże Cię, że brakuje szablonu 'myActionSuccess.php'. To jest normalne, w Symfony strona jest zawsze tworzona z akcji i szablonu.

CAUTION Adresy (nie nazwy domen) są bardzo wrażliwe na wielkości liter, więc Symfony też jest (nawet jeżeli nazwy metod są niewłaściwe w kodzie PHP). To oznacza, że jeśli dodasz metodę executemyaction(), albo executeMyaction(), i spróbujesz wywołać akcję myAction z przeglądarki, Symfony zwróci błąd 404 (brak strony).

SIDEBAR Adresy są częścią żądania

Symfony zawiera system routingu, który umożliwia separację pomiędzy aktualną nazwą akcji a formą adresu potrzebną do jej wywołania. Umożliwia to dowolne formatowanie adresu. Nie jesteś ograniczany przez strukturę plików czy parametrów. Adres URL może wyglądać tak jak Ty chcesz! Dla przykładu, wywołujesz akcję 'index' z modułu zwanego 'article', może to wyglądać tak:

http://localhost/myapp_dev.php/article/index?id=123

URL wyszukuje artykuł z bazy danych. W tym przykładzie, wyszukuje on artykuł (z parametrem id=123) w sekcji Europejskiej, który jest specyficzny dla finansów we Francji. Ale adres URL może być zapisany zupełnie inaczej, dzięki małej zmianie w pliku konfiguracyjnym 'routing.yml':

http://localhost/articles/europe/france/finance.html

URL nie jest wtedy tylko przyjacielski dla wyszukiwarek, ale jest to też ułatwienie dla użytkownika, który może używać paska adresu jako pseudo linii komend do tworzenia zapytań, jak w następującym URL-u:

http://localhost/articles/tagged/finance+france+euro

Symfony wie jak parsować i generować URL-e dla użytkownika. System routingu automatycznie pobiera parametry z adresu i udostępnia je w akcji. Formatuje on również odnośniki zawarte w żądaniu, dlatego wyglądają one elegancko. Dowiesz się o tym więcej w rozdziale nr 9.

W sumie, oznacza to, że droga jaką nazwiesz akcje w swojej aplikacji nie powinna mieć wpływu na drogę URL-i używanych do wywoływania ich. Nazwy metod wyjaśniają co aktualnie robią i jest to najczęściej czasownik w bezokoliczniku. Nazwy akcji mogą być w ogóle nie widoczne dla użytkownika końcowego, więc nie wahaj się używania wyraźnych nazw (jak pokazPoNazwie albo pokazZKomentarzami). Zaoszczędzisz na komentarzach w kodzie, aby wyjaśnić co dana funkcja robi. Ponadto Twój kod będzie prostszy do zrozumienia.

Dodawanie szablonu

Akcja wymaga szablonu aby się wyświetlić. Szablon jest plikiem ulokowanym w folderze 'templates/' w module. Nazwany jako akcja i terminator akcji. Domyślny terminator to 'success', więc szablon potrzebny akcji 'myAction' nazywa się 'myActionSuccess.php'.

Szablony są potrzebny tylko do prezentacji danych więc umieszczaj w nich jak najmniej kodu PHP. Szablon strona wyświetlająca napis "Witaj świecie!" może wyglądać tak prosto jak to przedstawiono na listingu 4-3.

Listing 4-3 - Szablon mymodule/templates/myActionSuccess.php

<p>Witaj świecie!</p>

Jeżeli musisz wykonać jakiś kod PHP w szablonie, powinieneś unikać zwykłej składni PHP (takiej jak pokazano na listingu 4-4), aby kod był zrozumiały dla programistów nie znających PHP. Niektóre funkcje sterujące mają alternatywną składnie, zaprezentowano ją na listingu 4-5.

Listing 4-4 - Zwykła składnia PHP, dobra dla akcja, ale zła dla szablonów

[php]
<p>Witaj świecie!</p>

Listing 4-5 - Alternatywna składnia PHP, dobra dla szablonów

[php]
<p>Witaj świecie!</p>
<?php if ($test): ?>
<p><?php echo time(); ?></p>
<?php endif; ?>

TIP Dobrym zwyczajem jest nie mieszanie kodu PHP z HTML. Nie powinieneś wyświetlać znaczników HTML w PHP. Jeżeli też otwierasz w jednej linii znacznik <?php, powinieneś w tej samej linii zamknąć!

Przesyłanie informacji z akcji do szablonu

Zadaniem akcji jest wykonywanie obliczeń, odzyskiwanie danych, test, ustawianie zmiennych do szablonów, aby były wyświetlone albo przetestowane. Symfony udostępnia właściwości klasy akcji (dostęp przez $this->nazwaZmiennej w akcji) w szablonie (dostępne przez $nazwaZmiennej). Listingi 4-6 i 4-7 pokazują jak przesłać dane z akcji do szablonu.

Listing 4-6 - Ustawienie właściwości akcji i uczynienie ich dostępnymi w szablonie

[php]
<?php

class mymoduleActions extends sfActions
{
  public function executeMyAction()
  {
    $dzisiaj = getdate();
    $this->godzina = $dzisiaj['hours'];
  }
}

Listing 4-7 - Szablon ma bezpośredni dostęp do właściwości akcji

<p>Witaj świecie!</p>
<?php if ($godzina >= 18): ?>
<p>A może powinienem powiedzieć dobry wieczór? Jest już <?php echo $godzina; ?>.</p>
<?php endif; ?>

NOTE Szablony od razu mają dostęp do kilku właściwości. W każdym szablonie można się odwoływać do następujących obiektów: '$sf_context', '$sf_request', '$sf_params' i '$sf_user'. Niedługo zobaczysz jak ich używać.

Gromadzenie informacji od użytkownika (formularze)

Formularze są dobrym sposobem na uzyskanie danych od użytkownika. Pisanie formularzy w HTML może być czasem niewygodne. W Symfony możesz umieszczać formularze w tradycyjny sposób, albo użyć pomocnika dostarczanego przez Symfony. Dzięki niemu pisanie formularzy staje się prostsze. Na listingu 4-8 pokazano jak umieszczać formularze w tradycyjny sposób.

Listing 4-8 - Szablony mogą zawierać zwykły kod HTML formularzy

<p>Witaj świecie!</p>
<?php if ($godzina >= 18): ?>
<p>A może powinienem powiedzieć dobry wieczór? Jest już <?php echo $godzina; ?>.</p>
<?php endif; ?>
<form method="post" target="/myapp_dev.php/mymodule/anotherAction">
  <label for="name">What is your name?</label>
  <input type="text" name="name" id="name" value="" />
  <input type="submit" value="Ok" />
</form>

Pomocnik to funkcja napisana w PHP. Wyświetla ona kod HTML. Jest to szybsza metoda. Używając pomocników Symfony możesz uzyskać taki sam efekt jak na listingu 4-8. Sposób ten przedstawiony jest na listingu 4-9.

Listing 4-9 - Używanie pomocników jest szybsze i prostsze, niż pisanie tagów HTML

<p>Witaj świecie!</p>
<?php if ($godzina >= 18): ?>
<p>A może powinienem powiedzieć dobry wieczór? Jest już <?php echo $godzina; ?>.</p>
<?php endif; ?>
<?php echo form_tag('mymodule/anotherAction') ?>
  <?php echo label_for('name', 'Jak się nazywasz?') ?>
  <?php echo input_tag('name') ?>
  <?php echo submit_tag('Ok') ?>
</form>

SIDEBAR Pomocniki są po to aby Ci pomóc

Jeżeli przyglądając się przykładowi na listingu 4-9 nadal myślisz, że wersja zawierająca pomocniki nie jest naprawdę szybka to zobacz następny przykład:

[php]
<?php
$card_list = array(
  'VISA' => 'Visa',
  'MAST' => 'MasterCard',
  'AMEX' => 'American Express',
  'DISC' => 'Discover');
echo select_tag('cc_type', options_for_select($card_list, 'AMEX'));
?>

To samo, tyle, że w HTML:

[php]
<select name="cc_type" id="cc_type">
  <option value="VISA">Visa</option>
  <option value="MAST">MasterCard</option>
  <option value="AMEX" selected="selected">American Express</option>
  <option value="DISC">Discover</option>
</select>

Korzyści z używania pomocników w szablonach są następujące: szybkość kodowania, przejrzystość kodu. Jedyna cena jaką się płaci to czas poświęcony na nauczenie się ich.

Używanie skróconych tagów (<?, zamiast <?php) nie jest polecane. Nie działają ona na domyślnej konfiguracji PHP. Ponadto podczas deklaracji XML może wystąpić tak zwany 'parse error'.

Więcej o pomocnikach dowiesz się z rozdziału nr 10.

Linki do innych akcji

Już wiesz, że jest pewna różnica między nazwą akcji a URL-em do wywołania jej. Więc jeżeli stworzysz link do akcji 'anotherAction' w szablonie tak jak pokazano na listingu 4-10, to zadziała on tylko na domyślnie ustawionym routingu. Jeżeli się później zdecydujesz na zmianę wyglądu URL-a, będziesz musiał przerobić wszystkie linki w szablonach.

Listing 4-10 - Hiperłącza, zwykły HTML

[php]
<a href="/myapp_dev.php/mymodule/anotherAction?name=anonymous">
  Nigdy nie ujawniłem swojego imienia
</a>

Aby uniknąć tego typu sytuacji, powinieneś zawsze używać pomocnika 'link_to()', który sam stworzy hiperłącze do akcji. Listing 4-11 przedstawia użycie tego pomocnika.

Listing 4-11 - Pomocnik link_to()

[php]
<p>Witaj świecie!</p>
<?php if ($godzina >= 18): ?>
<p>A może powinienem powiedzieć dobry wieczór? Jest już <?php echo $godzina; ?>.</p>
<?php endif; ?>
<?php echo form_tag('mymodule/anotherAction') ?>
  <?php echo label_for('name', 'Jak się nazywasz?') ?>
  <?php echo input_tag('name') ?>
  <?php echo submit_tag('Ok') ?>
  <?php echo link_to('Nigdy nie ujawniłem swojego imienia','mymodule/anotherAction?name=anonymous') ?>
</form>

Rezultat HTML będzie taki sam jak poprzednio, z tą różnicą, że po zmianie reguł routingu nie będziesz musiał poprawiać URL-i.

Pomocnik 'link_to()', jak i inne pomocniki, przyjmuje inne opcjonalne parametry. Listing 4-12 pokazuje przykład użycia opcjonalnych argumentów.

Listing 4-12 - link_to() - opcjonalne argumenty

[php]
<?php
// Opcje jako tablica asocjacyjna
echo link_to('Nigdy nie ujawniłem swojego imienia', 'mymodule/anotherAction?name=anonymous',
  array(
    'class'    => 'special_link',
    'confirm'  => 'Jesteś pewien?',
    'absolute' => true
) ?>

// Argumenty jako string
<?php echo link_to('Nigdy nie ujawniłem swojego imienia', 'mymodule/anotherAction?name=anonymous',

'class=special_link confirm=Jesteś pewien? absolute=true') ?>

// Obydwa rozwiązania zwrócą taki sam wynik
<a class="special_link" onclick="return confirm('Jesteś pewien?');"
href="http://localhost/myapp_dev.php/mymodule/anotherAction/name/anonymous">
Nigdy nie ujawniłem swojego imienia</a>

Ilekroć użyjesz pomocnika Symfony generującego kod HTML, możesz zawsze dodać opcjonalne atrybuty (jak atrybut 'class' w przykładzie na listingu 4-12). Pomocniki Symfony zawsze generują poprawny kod xHTML.

NOTE Ponieważ składnia string wymaga dodatkowego parsowania, jest ona trochę wolniejsza od składni tablicowej.

W rozdziale nr 9 poznasz dodatkowe opcje pomocników.

Pobieranie informacji z żądań

Jeżeli użytkownik przesłał jakieś informacje przez formularz (żądanie POST) czy przez adres URL (żądanie GET) zawsze możesz pobrać te informacje dzięki metodzie 'getRequestParameter()' z obiektu klasy sfActions. Listing 4-13 pokazuje jak w akcji 'anotherAction' pobrać wartość 'name'.

Listing 4-13 - Pobieranie danych z danych żądania

[php]
<?php

class mymoduleActions extends sfActions
{
  ...

  public function executeAnotherAction()
  {
    $this->name = $this->getRequestParameter('name');
  }
}

Jeżeli działania na danych z żądania są proste, nie musisz używać do tego akcji w kontrolerze. W szablonie masz dostęp do obiektu '$sf_params', który oferuje metodę 'get()' do pobierania danych żądania. Jeżeli akcja 'executeAnotherAction()' jest pusta, listing 4-14 pokazuje jak w szablonie pobieramy te same parametry.

Listing 4-14 - Pobieranie Danych bezpośrednio w szablonie

[php]
<p>Witaj, <?php echo $sf_params->get('name') ?>!</p>

NOTE Dlaczego nie używać tablic $_POST, $_GET czy $_REQUEST ? Ponieważ, gdy URL przyjmuje inną postać niż oryginalna (np. http://localhost/articles/europe/france/finance.html) nie ma możliwości pobrania danych bezpośrednio, tylko system routingu może to zrobić. Ponadto jesteś automatycznie chroniony przed tzn. 'wstrzyknięciami kodu'.

Obiekt $sf_params jest bardziej pomocny w pobieraniu danych niż metoda 'getRequestParameter()'. Dla przykładu jeżeli chcesz sprawdzić istnienie parametru żądania, możesz w prosty sposób użyć metody $sf_params->has(), a później pobrać go za pomocą metody get(), tak jak pokazano na listingu 4-15.

Listing 4-15 - Testowanie czy parametr żądania istnieje w szablonie

[php]
<?php if ($sf_params->has('name')): ?>
  <p>Witaj, <?php echo $sf_params->get('name') ?>!</p>
<?php else: ?>
  <p>Witaj, Janie Kowalski!</p>
<?php endif; ?>

Możesz zrobić to w prostszy sposób, podając metodzie get() drugi parametr.

[php]
<p>Witaj, <?php echo $sf_params->get('name', 'Janie Kowalski') ?>!</p>

Podsumowanie

W Symfony, strony są skomponowane jako akcje (metoda w pliku 'actions/actions.class.php' z prefixem 'execute') i szablon (plik w folderze 'templates/', najczęściej zakończony 'Success.php'). Są one pogrupowane w moduły, zależnie od ich funkcji w aplikacji. Pisanie szablonów ułatwiają pomocniki, które są funkcjami zwracającymi kod HTML.

Możesz już napisać całą aplikację z Symfony. Ale zajmie Ci jednak to dużo czasu, nie poznałeś jeszcze wszystkich możliwości Symfony. Dlatego nie przestawaj czytać tej ksiązki.