Strona główna
O mnie
Projekty
Publikacje
Linki
|
|
Uwaga: Druga część artykułu, pt. "Zaawansowane możliwości Smarty"
znajduje się tutaj
Jedna z głównych cech języka PHP - umieszczanie kodu wraz z HTMLem - choć na początku może się
wydawać wielką zaletą, nie w każdej sytuacji nią jest. W przypadku dużych aplikacji, tworzonych przez kilku
ludzi, ten sposób programowania może się bardzo niekorzystnie odbić na wydajności zespołu oraz czasie
potrzebnym na modyfikację i aktualizację aplikacji. Każda zmiana szaty graficznej będzie wymuszała
zaangażowanie programisty, który wprowadzi lub zmodyfikuje (w wielu plikach) odpowiednio kod HTML.
Ingerencja w kod skryptu może spowodować powstanie błędów (choćby popularne błędy ze znakami " i '), które
będzie trzeba wyłapać podczas żmudnych testów.
Wykorzystanie szablonów umożliwia pełne odseparowanie warstwy prezentacyjnej od warstwy
biznesowej aplikacji. Grafik może dowolnie zmieniać szatę graficzną bez obawy, że cokolwiek popsuje w
skrypcie. Natomiast programista nie musi integrować HTML'a z kodem PHP co znacznie zwiększa
przejrzystość programu i ułatwia jego późniejszą pielęgnację.
Technika szablonów polega na stworzeniu zwykłych plików HTML (zwanych dalej szablonami)
zawierających specjalne znaczniki (w większości systemów można użyć znacznika o postaci {zmienna} lub
{$zmienna}) następnie programista w aplikacji definiuje znaczniki i przypisuje im wartości ze zmiennych PHP
lub bezpośrednio z łańcucha znaków. Każdorazowo przy przetwarzaniu skryptu system szablonów wyszukuje
wszystkie znaczniki użyte w szablonie i podstawia pod nie odpowiednie wartości.
Programista definiuje tylko znacznik szablonu oraz przypisuje do niego wartość, nie interesuje jego jak
i gdzie będzie wyświetlana zawartość zmiennej. Natomiast grafik podczas modyfikacji szaty graficznej może
dowolnie zmieniać położenie znaczników oraz ich formatowanie bez obawy, że jego zmiany będą miały wpływ
na nieprawidłowe działanie aplikacji.
Zalety i wady
Niestety żadne rozwiązanie, czy też technologia nie jest pozbawiona wad z którymi musimy się pogodzić, jeśli
zamierzamy ją stosować. Tak także jest z systemami szablonów jednak ich zalety przeważają wady oraz
kompensują zainwestowany czas potrzebny na opanowanie tej techniki.
Do zalet szablonów należy zaliczyć:
- odseparowanie kodu aplikacji od jej warstwy prezentacyjnej
- tworzenie kodu bardziej przejrzystego i łatwiejszego w pielęgnacji
- zwiększenie wydajności zespołu, który teraz nie musi dublować się przy wprowadzaniu modyfikacji
- znaczne zmniejszenie ilości kodu, a tym samym potencjalnych miejsc w których mogą pojawić się
błędy
- ułatwienie tworzenia wielu wersji szat graficznych w serwisach, które umożliwiają użytkownikowi
dokonanie wyboru szaty graficznej lub warunkują jej wybór np. na podstawie pory dnia czy też roku.
Wada szablonów jest tylko jedna:
- nieznaczne spowolnienie działania serwisu spowodowane przetwarzaniem szablonów.
W sieci można znaleźć kilkanaście systemów szablonów o różnej funkcjonalności, sposobie obsługi
oraz szybkości działania. Wybranie więc odpowiadającego nam systemu nie jest zbyt proste. Przy jego wyborze
powinniśmy się kierować takimi czynnikami jak rodzaj funkcji jakie udostępnia system. Oprócz prostego
podstawiania znaczników, niezbędne są również operacje na blokach (sekcjach) - pozwalające grupować
wybrany fragment szablonu oraz wielokrotnie go przetwarzać (w pętli) - funkcja ta jest przydatna np. przy
generowaniu zmiennej liczby rzędów tabeli na podstawie rekordów pobranych z bazy danych.
Drugim ważnym czynnikiem wyboru jest sposób obsługi. Niestety jest on bardzo subiektywny, więc
jedyną możliwością doboru właściwego systemu jest zapoznanie się z kilkoma najbardziej popularnymi
rozwiązaniami.
Test wydajnościowy
Przeglądając zasoby sieci można znaleźć zaledwie kilka testów porównujących wydajność systemów
szablonów. W większości są one tworzone przez autorów klas, więc badają oni zwykle takie przypadki
zastosowania szablonów w których ich system wypada najlepiej na tle konkurencji. Przez to wyniki testów są
mało wiarygodne, a badane zastosowania niezbyt interesujące np. 100 krotne przetwarzanie 10 kB szablonu
zawierającego 15 znaczników.
Postanowiłem więc stworzyć test, który opierałby się o praktyczne zastosowanie szablonów w
prawdziwych aplikacjach. Test podzieliłem na dwie części, przedstawiające strony WWW prezentujące dane na
dwa sposoby:
1. Strona wyświetlająca dane na temat jednego klienta.
Test polegał na prostym podstawieniu wartości pod 15 znaczników znajdujących się w pliku HTML o rozmiarze
1889 bajtów.
2. Tabela z 20 wierszami zawierającymi szereg informacji o klientach.
Do wyświetlenia danych w tabeli wykorzystano operacje na bloku powielanym 20 razy. Każdy wiersz zawierał
po 6 znaczników. Dodatkowo zastosowano proste podstawienie 6 znaczników, bardzo typowe przy tego rodzaju
stronie np. wyświetlenie ilości zwracanych rekordów, tekstu informacyjnego, nawigacji po stronach z wynikami
itp.
Do testu zakwalifikowałem 8 najbardziej popularnych systemów szablonów, które posiadały możliwość
obsługi bloków. Testy zostały wykonane na komputerze: Duron 800, 128 MB RAM, dysk Seagate Barracuda III;
pracującym pod kontrolą systemu Linux Mandrake 8.1, Apache 1.3.20 oraz PHP 4.2.1. Podczas trwania testów
komputer nie był obciążony innymi zadaniami.
Na test składały się dwa rodzaje pomiarów: czas wykonania skryptu uruchomionego za pomocą
przeglądarki WWW oraz ilość stron wywołanych w ciągu sekundy, mierzonych za pomocą programu
ApacheBench 1.3 c (polecenie ab -n300 http://localhost/artykul/nazwa_systemu/nazwa_testu).
Test ten był także dobrą okazją do sprawdzenia jaki wpływ na wydajność ma zastosowanie programów
typu PHP accelerator, które rozszerzają język PHP o funkcje automatycznie buforujące wyniki działania
skryptów na dysku.
Pomiar czasu dla każdego systemu był wykonywany 4 razy (zachowując ok. 5 sekundową przerwę
pomiędzy odświeżeniami strony), następnie po odrzuceniu pierwszej (największej) wartości obliczana była
średnia arytmetyczna. Tak samo było w przypadku stosowania programu ab z tym, że wykonywano tylko 3
pomiary.
O kolejności w tabelach wyników decydowała średnia liczba wywołań na sekundę obliczona z wyniku
systemu przy PHP accelerator'ze włączonym i wyłączonym.
Rysunek 1. Wyniki testów wydajnościowych
Wyniki testów mogą być dużym zaskoczeniem (a nawet szokiem) dla zwolenników Smarty. Mimo całej
zaawansowanej techniki kompilacji system ten jest bardzo wolny w przypadku stosowania czystego PHP,
zwycięża jednak w obu testach gdy włączymy obsługę PHP acceleratora.
Osoby, które potrzebują największej wydajności i nie mogą zainstalować PHP acceleratora lub
programu o podobnych możliwościach będą musiały wybrać inny system np. Bugi, Phemplate.
Wprowadzenie do Smarty
Smarty jest jednym z najbardziej rozbudowanym systemów szablonów, oferuje unikalne opcje mające
na celu zwiększenie szybkości działania systemu oraz ułatwienie pracy osobom przygotowującym szablony
stron. Autorami projektu Smarty są takie znakomitości świata PHP jak Monte Ohrt i Andrei Zmievski
(jeden z głównych programistów rozwijających język PHP).
W celu przyspieszenia pracy systemu zastosowano technikę kompilacji, polegającą na jednokrotnym
przetwarzaniu szablonu do postaci zwykłego skryptu PHP, przy następnych wywołaniach Smarty korzysta ze
skompilowanego szablonu. Jeśli dokonamy modyfikacji w szablonie, system wykryje to (gdy jest włączona
opcja compile_check) i dokona ponownej kompilacji. Z założenia mechanizm ten miał drastycznie przyspieszyć
wykonywanie skryptu, działa to tak jak planowano tylko w przypadku stosowania akceleratora języka PHP np.
PHP accelerator.
Wśród innych zaawansowanych cech Smarty należy wymienić: system buforujący (cache)
wygenerowanych stron, modyfikatory zmiennych, funkcje szablonów, wtyczki (plug-ins), filtry i pliki
konfiguracyjne.
Instalacja Smarty
Czynność ta jest bardzo prosta, polega na utworzeniu w katalogu naszego projektu, dwóch podkatalogów
templates, templates_c oraz cache i configs (oba opcjonalnie).
Do tego katalogu także należy skopiować z
archiwum systemu Smarty: katalog plugins oraz pliki Smarty.class, Smarty_Compiler.class oraz
Config_File.class (opcjonalnie). Podstawowa struktura projektu została pokazana na rys2.
Katalogi templates_c oraz cache (oznaczone na rysunku kolorem czerwonym) musza mieć ustawione prawa do
zapisu dla użytkownika na którego prawach działa serwer WWW. W przypadku użytkownika apache starczą
prawa 700 oraz ustawiony właściciel jako apache:apache. Oczywiście w warunkach testowych możemy
zaryzykować nadanie praw 777.
|
|

Rysunek 2. Podstawowa struktura projektu używającego Smarty |
W dalszej części artykułu przedstawiłem podstawowe informacje umożliwiające rozpoczęcie
korzystania ze Smarty. Więcej wiadomości czytelnik znajdzie w bardzo dobrej i przystępnie napisanej
dokumentacji tego projektu.
Pierwszy szablon
Poznawanie systemu zaczniemy od bardzo prostego przykładu, który realizuje podstawienie dwóch znaczników
w naszym szablonie.
Tworzymy plik szablonu o nazwie p1.tpl (oczywiście nazwa i rozszerzenie może być dowolne) i
umieszczamy w katalogu templates. Zawartość tego pliku została pokazana na listingu 1.
W podanym przykładzie mamy dwa znaczniki {$tytul} oraz {$test_znacznika},
teraz napiszemy skrypt zamieniający znaczniki na wybrane przez nas wartości.
Skrypt należy zapisać w głównym katalogu projektu.
Jak widać obsługa Smarty nie wymaga stosowania żadnych zawiłych konstrukcji. Po zaimportowaniu biblioteki,
tworzymy obiekt $smarty (linia 5) następnie przypisujemy wartości do znaczników za pomocą konstrukcji:
$smarty->assign('nazwa_znacznika', 'Wartość lub nazwa $zmiennej PHP lub wyrażenie matematyczne');
Rozpoczęcie przetwarzania szablonu zaczyna się po wywołaniu metody display, której argumentem jest nazwa
szablonu.
|
|
<html>
<head>
<meta http-equiv="Content-type"
content="text/html;charset=ISO-8859-2">
<title>{$tytul}</title>
</head>
<body bgcolor="#FFFFFF">
{$test_znacznika}
</body>
</html>
Listing 1 Pierwszy szablon - p1.tpl
<?php
$tytul = 'Szablony - przykład 1';
include('Smarty.class.php');
$smarty = new Smarty;
$smarty->assign('tytul', $tytul);
$smarty->assign('test_znacznika',
'To naprawdę działa!');
$smarty->display('p1.tpl');
?>
Listing 2 Podstawianie wartości pod znaczniki
|
Przejdźmy teraz do bardziej zaawansowanych funkcji a mianowicie:
Operacje na blokach
Jak wcześniej wspomniałem blok to wydzielony fragment szablonu, który będzie powielany n razy, co przydaje
się do generowania różnych tabel, list itp. Aby za bardzo nie zaciemniać przykładu do wcześniej użytego
szablonu dodamy blok który będzie wstawiał 10 liczb: 0, 5, 10 ...45.
Zapiszmy powyższy przykład do pliku p2.tpl. Pojawiły się nowe elementy, które wymagają wytłumaczenia.
Cały blok zawarty jest w znacznikach {section ....} oraz {/section}. Będzie on powielany loop razy. W tym
przypadku 10, ale może to być oczywiście określone za pomocą zewnętrznej zmiennej, która będzie zależna np.
od ilości rekordów zwróconych z zapytania SQL.
Znacznik {$liczby[blok]} oznacza, że znacznik {$liczby} jest tablicą, która będzie indeksowa za pomocą nazwy
tego bloku - blok - i będzie się zmieniać od 0 do loop, przy czym możliwe jest także określenie od jakiego
indeksu ma się zaczynać odliczanie (np. start=5) oraz z jakim krokiem (np. step = 10).
Przypisywanie do znacznika zmiennych tablicowych wygląda dokładnie tak samo jak w przypadku
zwykłych zmiennych. Jeśli chcielibyśmy wprowadzić zmienną określającą ilość powtórzeń sekcji to w pliku
szablonu stosujemy konstrukcję loop=$ile, a skrypcie obsługujemy znacznik {$ile} tak samo jak każdy inny.
|
|
<html>
<head>
<meta http-equiv="Content-type"
content="text/html;charset=ISO-8859-2">
<title>{$tytul}</title>
</head>
<body bgcolor="#FFFFFF">
{$test_znacznika}<br><br>
Test bloku:
{section name=blok loop=10}
{$liczby[blok]}<br>
{/section}
<br>Koniec bloku
</body>
</html>
Listing 3 Szablon prezentujący operacje na blokach - p2.tpl
<?php
$tab = array (0,5,10,15,20,25,30,35,40,45);
include('Smarty.class.php');
$smarty = new Smarty;
$smarty->assign('tytul',
'Szablony - przykład 2');
$smarty->assign('test_znacznika',
'To naprawdę działa!');
$smarty->assign('liczby', $tab);
$smarty->display('p2.tpl');
?>
Listing 4 Przypisanie zmiennej tablicowej do sekcji szablonu
|
Modyfikatory
Pozwalają grafikowi na manipulowanie (w dość małym, lecz istotnym zakresie) informacją jaka
zostanie podstawiona pod znaczniki. Z najważniejszych modyfikatorów należy wymienić: formatujące datę,
obcinające łańcuch do podanej długości, zmieniające wszystkie litery w łańcuchu na duże lub małe,
podstawiające przygotowaną informację gdy zmienna określająca znacznik jest pusta lub jest on nie
zdefiniowany.
W przykładzie nie definiujemy znacznika {$tytul} dlatego zostanie wstawiona wartość domyślna.
Modyfikator default może posłużyć do wstawienia znaku spacji ( ) w te komórki tabeli gdzie
spodziewamy się, że skojarzona ze znacznikiem zmienna może być pusta. Istotne to jest w przypadku Netscape
Navigatora, który wymaga aby komórka miała jakąś zawartość.
Przykład ten nie wyczerpywał wszystkich możliwości modyfikatorów, które są kolejnym krokiem do
odseparowania pracy programisty oraz grafika.
|
|
<html>
<head>
<meta http-equiv="Content-type"
content="text/html;charset=ISO-8859-2">
<title>{$tytul|default:"nie podano"}</title>
</head>
<body bgcolor="#FFFFFF">
{$znacznik}<br>
{$znacznik|upper}<Br>
{$znacznik|truncate:10:"":true}
</body>
</html>
Listing 5 Szablon prezentujący zastosowanie modyfikatorów znaczników - p3.tpl
<?php
include('Smarty.class.php');
$smarty = new Smarty;
$smarty->assign('znacznik', 'Jakiś dłuższy
tekst, który będziemy modyfikować.');
$smarty->display('p3.tpl');
?>
Listing 6 Zastosowanie modyfikatorów
|
Instrukcje warunkowe
Pozwalają na określenie zachowania szablonu na podstawie stanu (zawartości) znacznika, za pomocą
instrukcji warunkowej {if} {/if}. Oprócz dobrze znanych warunków np. < > !=, Smarty umożliwia stosowanie
tak specyficznych jak np. is even (parzysty), is odd (nieparzysty).
Jednym z najczęstszych zastosowań instrukcji warunkowych jest naprzemienne kolorowanie tła wierszy
tabeli.
Jeśli indeks sekcji b1 jest parzysty zostanie wstawiony tekst #E0F6FF w przeciwnym wypadku #ADD8E6.
W rzeczywistej aplikacji $row_cnt może być określany np. na podstawie ilości rekordów zwróconych za pomocą
zapytania SQLowego. Dla MySQL'a można by więc napisać: $row_cnt = mysql_num_rows($result);
|
|
<html>
<head>
<meta http-equiv="Content-type"
content="text/html;charset=ISO-8859-2">
<title>Koloryzowanie naprzemiene tabeli</title>
</head>
<body bgcolor="#FFFFFF">
<table width=100 border=0>
{section name=b1 loop=$row_cnt}
<tr bgcolor="{if $smarty.section.b1.index
is even}#E0F6FF{else}#ADD8E6{/if}">
<td>kolumna 1</td>
<td>kolumna 2</td>
{/section}
</table>
</body>
</html>
Listing 7 Szablon prezentujący instrukcje warunkowe - p4.tpl
<?php
$row_cnt = 10;
include('Smarty.class.php');
$smarty = new Smarty;
$smarty->assign('row_cnt', $row_cnt);
$smarty->display('p4.tpl');
?>
Listing 8 Testowanie instrukcji warunkowej
|
Komentarze oraz bloki nie przetwarzane
W szablonie możemy umieścić komentarze, które będą całkowicie ignorowane przez system i nie znajdą się w
kodzie strony wynikowej. Komentarze umieszczamy między znakami {* Komentarz *}. Jeśli chcemy oznaczyć
jakiś fragment szablonu, aby nie był przetwarzany przez Smarty, należy otoczyć go znacznikami {literal} kod
nie przetwarzany {/literal}. Czynność ta jest konieczna w przypadku stosowania w szablonie CSS lub JS, ze
względu na występowanie w nich znaków { i } które byłyby błędnie interpretowane przez system szablonów.
Podsumowanie
Artykuł ten miał na celu nakłonienie czytelników do rozważenia zastosowania szablonów w swoich
projektach. Mimo czasu jaki trzeba poświęcić na zapoznanie się zespołu z tą techniką, warto spróbować,
ponieważ dobrze zastosowane szablony zmniejszają znacznie czas potrzebny na tworzenie kodu i jego
modyfikacje. Ograniczają również konieczność częstych kontaktów pomiędzy członkami zespołu.
Mam nadzieje, że prezentowany test ułatwi czytelnikom wybór najwłaściwszego dla nich systemu
szablonów. Dzięki zamieszczeniu na CD pełnego kodu testu będą mogli również zapoznać się z podstawami
obsługi testowanych systemów oraz wykonać podobny test we własnym środowisku.
Mimo słabych wyników czasowych (bez zastosowania PHP acceleratora) polecam system Smarty,
który udostępnia najwięcej możliwości jest prosty w użyciu oraz ma bardzo dobrą i obszerną dokumentację.
Linki
Bugi Template http://www.bugi.biz
Easy Template System http://ets.sourceforge.net
PEAR http://pear.php.net
Phemplate http://pukomuko.esu.lt/phemplate/
Smarty http://smarty.php.net/
TemplatePower http://templatepower.codocad.com
vLIB Template http://www.activefish.com/vlib
xTemplate http://sourceforge.net/projects/xtpl
PHP Accelerator http://www.php-accelerator.co.uk
szablony.zip (102 KB) - Listingi, test wydajnościowy wraz ze źródłami systemów szablonów
Artykul został pierwotnie opublikowany w magazynie Software 2.0 Extra! nr 1 - "PHP Starter Kit" (10/2002) |
www.software.com.pl |
|