Professional Documents
Culture Documents
AKTUALNOŚCI 6
Krzysztof Trynkiewicz
Nasz magazyn ukazuje się w dwóch językach! Reflection API to zestaw klas i funkcji, przy po-
mocy których programista może zdobyć infor-
mację o budowie dowolnej klasy, obiektu lub
polskim francuskim funkcji, wbudowanej lub napisanej w PHP, Piotr
prezentuje nam jego możliwości.
Jeśli jesteś zainteresowany zakupem licencji na wydawanie naszych pism prosimy o kontakt:
Monika Godlewska monikag@software.com.pl tel.: 48 22 887 12 66, fax: 48 22 887 10 11
TRIKI W PHP 68
Listingi wszystkich opisywanych programów zostały zamieszczone na naszej stronie
internetowej www.phpsolmag.org/pl.
Łukasz Sosna
WYWIAD 74
PHP Solutions jest wydawany przez Software-Wydawnictwo Sp. z o.o.
KLUB TECHNICZNY i programy były poprawne, jednakże nie bierze odpowiedzialności za efekty wykorzystania ich; nie gwarantuje
także poprawnego działania programów shareware, freeware i public domain.
Uszkodzone podczas wysyłki płyty wymienia redakcja.
Zend Platform 2 80 Wszystkie znaki firmowe zawarte w piśmie są własnością odpowiednich firm
i zostały użyte wyłącznie w celach informacyjnych.
Ian Morse
Redakcja używa systemu automatycznego składu
Ian przedstawia Zend Platform 2 – dobrze za- Do tworzenia wykresów i diagramów wykorzystano program firmy
projektowaną i wysoce wydajną warstwę ser- Osoby zainteresowane współpracą prosimy o kontakt: cooperation@software.com.pl
werową. Druk: ArtDruk
Wysokość nakładu obejmuje również dodruki. Redakcja nie udziela pomocy technicznej w instalowaniu
i użytkowaniu programów zamieszczonych na płytach CD-ROM dostarczonych razem z pismem.
ZAPOWIEDZI 82 Sprzedaż aktualnych lub archiwalnych numerów pisma po innej cenie niż wydrukowana na okładce
– bez zgody wydawcy – jest działaniem na jego szkodę i skutkuje odpowiedzialnością sądową.
Kobiety w PHP?
Jak najbardziej! HotScripts – największa skryptoteka PHP
Na początku października tego roku, kobie-
ty programujące w PHP wreszcie ujawniły się.
Wraz z rozpowszechnieniem się wiadomości,
o powstaniu grupy dyskusyjnej przeznaczo-
W iększość deweloperów PHP jeśli
nie odwiedziła, to przynajmniej sły-
szała o HotScripts. Praktycznie każda apli-
nej głównie dla płci pięknej, deweloperzy PHP
ze zdumieniem odkryli, że kobiet w tym świat- kacja napisana w tym języku (chociaż nie
ku nie brakuje. Autorki projektu zostały podda-
ne wywiadowi, który teraz możemy przeczytać tylko – HotScripts kataloguje także aplika-
na stronie głównej projektu. Jeśli interesuje nas cje Flash, ASP i wiele innych) trafia do te-
trochę świeższe podejście do programowania
i mamy ochotę przeczytać ciekawy
go repozytorium. Tym samym, na witrynie
wywiad, warto odwiedzić adres http:// http://hotscripts.com znajdziemy ponad 11
www.phpwomen.org/wordpress/2006/10/22/ 000 skatalogowanych aplikacji PHP. Każ-
interview-with-founding-women/, jednak główną
siłą organizacji pozostaje forum, dostępne pod da z nich opatrzona jest opisem, przydzie-
adresem http://www.phpwomen.org/forum/ lona do odpowiednich kategorii. Podana
http://www.phpwomen.org
jest także jej licencja (oraz, ewentualnie,
Horda naciera na PHP cena) wraz z odnośnikiem do strony pro- nie mamy do wyboru blisko 100 kategorii!
Na popularności zyskuje ostatnio projekt o intry- jektu. Ogrom tych informacji pozwala na Na tym jednak potęga HotScripts się nie
gującej nazwie Horde. Jego podstawą jest fra-
mework o takiej samej nazwie, natomiast ilość sprawne wyszukanie żądanego skryptu w kończy. Serwis ten oferuje także recenzje
modułów na nim zbudowanych jest godna po- jednej z wielu kategorii: systemy blogowe, oraz download ponad 50 książek i 45 arty-
dziwu. Mamy więc do wyboru książki adresowe,
notatnik, harmonogram, menedżer plików oraz CMSy, chaty, organizery plików muzycz- kułów związanych z PHP, linkuje do ponad
klasy np. do sprawdzania i filtrowania e-ma- nych, fora, ankiety, liczniki, galerie... Łącz- 100 stron skupiających społeczność PHP,
ili, generujące kod oparty o technologię AJAX.
Projekt rozwija się dość prężnie, średnio co
zawiera informacje o 150 programach po-
miesiąc publikowana jest nowa wersja frame- mocnych przy pisaniu kodu, popartych po-
worka, wnosząca istotne modyfikacje. Całość nad tysiącem tutoriali, listą 35 agencji fre-
udostępniana jest na licencji GNU LGPL.
http://www.horde.org elancingowych, a wreszcie: linkami do
450 innych stron związanych z PHP. Na-
Łączymy PHP i ColdFusion leży więc pamiętać, że skryptorium, to je-
Fusebox to framework oparty o architekturę
MVC, mający na celu połączenie aplikacji PHP dynie mała część serwisu HotScripts. Od-
i ColdFusion. Jak zachwalają autorzy, jego
wiedzając witrynę, pamiętajmy, by i nasze
głównym atutem jest szybkość wykonywania
kodu. Framework jest udostępniany na darmo- dzieło umieścić w największym repozyto-
wej licencji i z pewnością przypadnie do gustu rium skryptowym świata!
deweloperom, którzy znają już ColdFusion, lecz
potrzebują możliwości oferowanych przez PHP.
http://www.fusebox.org http://hotscripts.com
C
PHP Directory to projekt, w założeniu które-
zy nie często spotykamy się z pro- go jest skatalogowanie najistotniejszych linków
stymi problemami, których rozwiąza- powiązanych z tym językiem. W tym repozyto-
rium znajdziemy informacje o grupach dysku-
nia nie jesteśmy całkowicie pewni, mimo, syjnych, artykułach, pismach, newsach, aplika-
że zawiera ono ledwie kilkanaście linijek cjach IDE, konferencjach, publikacjach i wie-
kodu? Napisanie tego kodu nie stano- lu innych zagadnieniach kluczowych dla dewe-
loperów PHP. Stąd trafimy też na blogi wybit-
wi problemu, ale czas potrzebny na po- ności ze światka PHP. Chociaż PHP Directo-
łączenie się z serwerem, upload plików ry dopiero się rozwija, już teraz stanowi dosko-
nały zbiór linków dla głodnego informacji pro-
i ich egzekucja w przeglądarce to zbęd- gramisty.
ne sekundy, które odrywają nas od głów- no wywołana sesja skryptu. Dzięki takie- http://www.phpdirectory.com
nego toku myślenia przy programowaniu mu rozwiązaniu, w jednym oknie prze-
Miniaturki w PHP
większej aplikacji. Z pomocą przychodzi glądarki możemy sprawdzić kilka warian- z phpThumb()
php Interactive, umożliwiający wykonanie tów naszego kodu. Każdej zakładce mo- phpThumb() to rozwinięty skrypt, generujący
kodu PHP bezpośrednio z poziomu prze- żemy nadać unikalną nazwę. Interfejs miniaturki. Wynikowy obrazek może być więk-
szy lub mniejszy od oryginału. Obróbce może
glądarki. Po instalacji pakietu, wystarczy php Interactive zawiera także podręczną zostać poddana całość grafiki lub jej fragment.
wejść na nasz ustalony adres, by ujrzeć wyszukiwarkę, podobną do tej z http:// Dodane mogą zostać tło i obramowanie. Źró-
dłowy plik może być na serwerze zdalnym, lo-
stronę, na którą możemy wkleić nasz php.net, która niejednokrotnie przyda się kalnym, lub w bazie danych. Tworzenie obra-
kod PHP. Rezultat jego działania otrzy- w razie otrzymywania nieoczekiwanych zów GIF jest możliwe z lub bez biblioteki GD.
mamy po naciśnięciu jednego przycisku. wyników. Skrypt do działania nie wyma- Podobnie sprawa ma się z formatem BMP i bi-
blioteką ImageMagick. W przypadku posiadania
Ponieważ często zdarza się, że kod PHP ga żadnego dodatkowego oprogramo- zainstalowanej wersji tej ostatniej, możliwa jest
zwraca tekst zamknięty w znaczniki, de- wania (np. bazy danych), chociaż kata- generacja obrazu w każdym przez nią obsłu-
giwanym formacie. Poza tymi formatami, ma-
weloperzy projektu php Interactive udo- log z nim warto zabezpieczyć przed pu- my do wyboru PNG, JPEG i ICO. Dodatkowo,
stępnili dwie możliwości podejrzenia wy- blicznym dostępem. Projekt jest udostęp- autor udostępnił wiele przydatnych filtrów (roz-
mycie, cień, zaokrąglanie krawędzi, wyostrza-
ników wykonania kodu (ang. output): czy- niany na zasadach określonych w licen- nie, poziom kontrastu, sephia, negatyw itd.)
sty tekst (RAW), lub tekst sformatowany cji GNU GPL. oraz funkcję cachingu. Wygenerowane obrazy,
(HTML). Dodatkowo, do naszej dyspo- zgodne ze standardem EXIF, mogą być zapisy-
wane, eksportowane, bądź użyte bezpośrednio
zycji zostały oddane specjalne zakładki Licencja: GNU GPL. w innych aplikacjach.
(ang. tabs), każda z nich działa jak osob- http://www.hping.org/phpinteractive http://freshmeat.net/projects/phpthumb
Nowe e-booki
T ematy bezpieczeństwa sieci zawsze
są aktualne. Każdy specjalista z za-
kresu oprogramowania nie uniknął kwestii
związanych z programowaniem sieciowym.
Zarówno PHP i MySQL są nie odłącznym
elementem tej dziedziny.
Dopełniając się odpowiednio sta-
nowią poważne narzędzie o wielkich
możliwościach. Na płycie zamieścili-
śmy parę pozycji o powyższej tematy-
ce, które warto przejrzeć:
HITY
Pełna wersja kursu HTML
- MySQL Serwer 5
- XAJAX: Łatwy AJAX
dla programistów PHP
E-BOOKS
- Built Your Own Database Driven
Website Using PHP and MySQL
- PostgrSQL 8.1.4 Documentation
- MySQL 5.1 Reference Manual
na naszej stronie internetowej pod adresem www.phpsolmag.org/pl
Tworzymy aplikacje
okienkowe z PHP-Qt
Stopień trudności: lll
Thomas Möenicke
C
hoć PHP-Qt znajduje się we cie dla standardu D-BUS pod Linuk-
wczesnej fazie rozwoju, zaim- sem i Uniksem. Wspomniane wersje Qt
plementowano w nim już naj- umożliwiają również integrację aplikacji
ważniejsze technologie, co umożliwia z konkurencyjnym wobec KDE środowi-
tworzenie prostych aplikacji. Pokażemy skiem GNOME.
później, jak pisać w PHP programy ko- W najnowszej wersji PHP-Qt zosta-
rzystające z Qt na przykładzie kalkulato- ło zaimplementowanych 75 należących
ra. Zacznijmy jednak od ogólnego omó- do Qt klas. Następne wydanie, nad któ-
wienia Qt. rym trwają prace, ma zawierać prawie
Qt zawiera bibliotekę klas, a także wszystkie spośród wspomnianych 400
narzędzia ułatwiające tworzenie aplika- klas. Biblioteka Qt ma rozwinięty, doj-
cji oraz internacjonalizację. W tej pierw-
szej znajduje się ponad 400 klas odpo- Co powinieneś wiedzieć:
W SIECI wiedzialnych za tworzenie graficznych Powinieneś znać podstawy programo-
interfejsów użytkownika (GUI, ang. Gra- wania obiektowego. Przydatna będzie
phical User Interface), wygląd aplikacji również znajomość ogólnych zasad
1. http://php-qt.berlios.de tworzenia interfejsów graficznych (GUI)
– strona domowa PHP-Qt
okienkowych (layout), obsługę SQL-a, w Qt lub innych systemach widgetów
2. http://docs.trolltech.com/4.1 sieci, XML-a, internacjonalizację, współ- (np. wxWidgets czy GTK).
– dokumentacja Qt pracę z OpenGL i wiele innych. Qt4.1
3. http://www.trolltech.no
– strona główna firmy i 4.2 zawierają również silnik obsługi Co obiecujemy:
Trolltech PDF-ów, wsparcie dla tworzenia grafiki Pokażemy, jak korzystając z PHP-Qt
4. http://www.trolltech.com/ utworzyć w PHP aplikację korzystającą
products/qt/learnmore/ SVG, frameworki: Graphics-View oraz
z Qt (kalkulator) i objaśnimy podstawo-
classchart – klasa Qt 4.1 undo (cofanie operacji), arkusze sty- we zagadnienia związane z Qt.
lów dla widgetów (kontrolek) czy wspar-
rzały model obiektowy, a jej API jest ele- type casting). Kalkulator będzie umoż-
ganckie i przejrzyste, co ułatwia two- liwiał wykonywanie podstawowych ope-
rzenie aplikacji i czyni je przyjemniej- racji arytmetycznych. Będzie miał pa-
szym. Firma Trolltech (twórca Qt) roz- mięć do przechowywania liczb, wyświe-
powszechnia Qt4 na podwójnej licen- tlacz, klawiaturę numeryczną oraz przy-
cji (komercyjnej lub GNU GPL) dla plat- ciski służące do kasowania pojedyn-
form X11 (X-Window), MacOS X i MS czych cyfr lub całych wpisanych warto-
Windows. ści oraz wykonywania obliczeń.
Przejdźmy teraz do naszego kal- Rysunek 1. Kalkulator stworzony w PHP-Qt
kulatora (zob. Rysunek 1), na podsta- Aplikacje wPHP-Qt:
wie którego pokażemy, jak stosować zaczynamy Zaczynamy od utworzenia nowej in-
główne koncepcje Qt, takie jak sygnały Zanim jednak przejdziemy do kalkulato- stancji $app klasy QApplication. Dziedzi-
(ang. signals), sloty (ang. slots), dzie- ra, musimy wiedzieć, jak utworzyć okno czy ona z QCoreApplication i jest głów-
dziczenie, definiowanie wyglądu (lay- główne aplikacji. W tym celu przyjrzyj- ną klasą Qt, zarządzającą ustawieniami
out), łańcuchy, przeciążenie metod my się prostszemu przykładowi z Li- oraz interakcją z użytkownikiem (control
(overloading) oraz zmiana typów (ang. stingu 1. flow). Możemy przekazać parametry $ar-
gc i $argv do jego konstruktora.
Następnie tworzymy obiekt $window
Instalacja i szybki start klasy QWidget, która z kolei jest klasą ba-
Obecna wersja PHP-Qt pracuje wyłącznie pod Linuksem; planowane wydanie (port) dla zową dla wszystkich widgetów (kontro-
Windows nie zostało jeszcze ukończone.
lek). Jej zadaniem jest ich prezentacja na
Na dołączonej do pisma płycie CD PHP Solutions Live! umieszczamy zainstalowa-
ne, gotowe do pracy PHP-Qt wraz z omawianym przez nas przykładem. Jeśli chcesz za- ekranie oraz odbieranie zdarzeń. Z jej pól,
instalować PHP-Qt na swoim komputerze, musisz pobrać źródła najnowszego wydania slotów i metod mogą korzystać wszystkie
tej biblioteki pod adresem http://php-qt.berlios.de i rozpakować je na twardym dysku.. obiekty, które z niej dziedziczą. Obiekt
Opiszemy instalację wersji 0.0.3. Poza samym PHP-Qt potrzebne będą:
$window będzie głównym oknem naszej
źródła parsera PHP5.1 (lub nowszego), aplikacji. Ustawimy jego rozmiar metodą
źródła PHP-Qt, resize() na 200 (szerokość) i 120 pikse-
pliki nagłówkowe Qt 4.1 i skompilowana biblioteka Qt. li (wysokość).
Kolejnym obiektem, który utworzy-
Zalecana jest kompilacja PHP z użyciem prefiksu (parametr --prefix), aby zachować my, będzie przycisk (ang. button) $quit
obecną na dysku wersję PHP (jeżeli takową posiadamy). Jak zwykle, zaczynamy od wy- klasy QPushbutton. Przypiszemy mu na-
konania polecenia configure:
pis Quit, który się na nim ukaże i za-
./configure –prefix=/usr/local/php-5.1.1 gnieździmy go w oknie $window: w taki
make właśnie sposób umieszczamy kontrolki
w oknach. Następnie ustawimy współ-
make install (wykonujemy tę operację zalogowani jako root)
rzędne przycisku $quit (kolumna, wers,
Następnie przechodzimy do katalogu php_qt i wpisujemy:
szerokość, wysokość) używając jego
./configure metody setGeometry(). Ostatnią rze-
--with-php_qt[=/path/to/qtheaders] czą, którą zrobimy z naszym przyci-
--with-qtlib[=/path/to/qtlib]
skiem, bedzie przypisanie mu sygna-
--with-php-config=/usr/local/php-5.1.1/bin/php-config
łu clicked() odpowiadającego za je-
Ostatni parametr wskazuje skrypt php-config, drugi ścieżkę dostępu do skompilowanej bi- go kliknięcie myszką oraz slotu quit():
blioteki Qt, a pierwszy – pliki nagłówkowe Qt. Możemy teraz skompilować kod źródłowy w ten sposób kliknięcie tego przycisku
wykonując make install (musimy być zalogowani jako root). Po udanej kompilacji oraz będzie powodowało zakończenie dzia-
instalacji powinniśmy móc uruchomić tutoriale dołączone do pakietu PHP-Qt poleceniem: łania aplikacji . Dodajmy, że slot quit()
jest wbudowaną metodą klasy QAppli-
/usr/local/php-5.1.1/bin/php-qt/tutorials/t1/main.php
cation. Przypisując nazwę obiektu $app
Jesteśmy gotowi, aby napisać nasz pierwszy program: jak zwykle będzie to Hello World określamy też przynależność przycisku
(przykład z tutoriala 1), którego efekt działania pokazujemy na Rysunku 2: $quit do naszej aplikacji.
Teraz pozostało wyświetlenie okna
if(!extension_loaded('php_qt')) {
na ekranie ($window->show() oraz uru-
dl('php_qt.' . PHP_SHLIB_SUFFIX);
} chomienie głównej pętli naszej aplika-
$app = new Qapplication($argc,$argv);
$hello = new QPushButton("Hello world!");
$hello->show();
$app->exec();
cji ($app->exec()). Zostanie ona za- że klasy Calculator i Button są do- Okno główne:
trzymana jeżeli główny widget (okno) stępne w pakiecie PHP-Qt (examples/ dziedziczenie
zostanie zniszczony lub po wywoła- calculator/calculator.php). Tam też mo- Jak już wspomnieliśmy, okno główne
niu exit(). żemy od razu przetestować jego dzia- Calculator jest klasą pochodną wobec
łanie. QDialog, tak więc wszystkie metody, sy-
Tworzymy kalkulator Przejdźmy teraz do skryptu ma- gnały i sloty tej drugiej są dziedziczone.
Przyjrzyjmy się teraz budowie kalkula- in.php. Na samym początku sprawdza- Możemy je przystosować do naszych po-
tora. Składa się on z dwóch klas: Cal- my, czy rozszerzenie php_qt zostało za- trzeb i tworzyć nowe, np. te, które odno-
culator (calculator.php) i Button (but- ładowane i jeśli nie, ładujemy je. Następ- szą się do przycisków.
ton.php) oraz głównego skryptu ma- nie dołączamy plik calculator.php i po- Potrzebujemy metod obsługujących
in.php, który uruchamia całą aplikację dobnie jak w naszym poprzednim przy- działania użytkownika, czyli slotów. Bę-
(Listing 2). Plik calculator.php zawie- kładzie, tworzymy instancję $app kla- dą nimi: digitClicked() (kliknięcie klawi-
ra 390 linijek kodu, więc nie będziemy sy QApplication. Potem inicjujemy okno sza cyfry), unaryOperatorClicked () (klik-
go szczegółowo omawiać: skupimy się główne kalkulatora, które u nas jest in- nięcie przycisku .....................), additive-
na tych fragmentach, które będą nam stancją $calc klasy Calculator, pokazu- OperatorClicked () (kliknięcie przycisku
potrzebne do wyjaśnienia jego działa- jemy je ($calc->show() i uruchamiamy dodawania), multiplicativeOperator-
nia. Kompletny skrypt main.php, a tak- pętlę główną aplikacji ($app->exec()). Clicked () (kliknięcie przycisku mnoże-
nia), equalClicked () (kliknięcie przycisku
Listing 1. Prosty przykład działania Qt: okienko zawierające przycisk Quit równa się), pointClicked() (kliknięcie
przycisku kropki), changeSignClicked ()
$app = new QApplication($argc,$argv); (kliknięcie przycisku +/- służącego do
zmiany znaku), backspaceClicked () (klik-
$window = new QWidget();
$window->resize(200,120);
nięcie backspace, czyli kasowanie cy-
fry), clear() (czyszczenie wpisanej lub
$quit = new QPushButton("Quit", $window); wyliczonej wartości), clearAll() (czysz-
$quit->setGeometry(10, 40, 180, 40); czenie całego wyświetlacza), clearMem-
ory() (czyszczenie pamięci kalkulatora),
$quit->connect($quit,SIGNAL("clicked()"),$app,SLOT("quit()"));
read _ Memory () (odczyt pamięci kalkula-
slotów). Slot jest wywoływany po wysła- momencie zniszczenia obiektu, które- slocie. Przyciski są tworzone z uży-
niu przez widget połączonego z nim sy- go one dotyczą. Obecna wersja PHP- ciem wspomnianej już metody create-
gnału. Qt nie obsługuje jeszcze slotów z pa- Button(), która wymaga dwóch para-
Sloty to zwyczajne metody w mode- rametrami: funkcjonalność ta jest pla- metrów: opisu, który zostanie wyświe-
lu obiektowym PHP5, które mogą być nowana w najstępnych wersjach tej bi- tlony na klawiszu oraz slotu. Slotami
publiczne (public), chronione (protec- blioteki. będą metody wymienione w zmiennej
ted) lub prywatyne (private) i może- Wszystkie spośród używanych przez $slots z Listingu 3, które będą połą-
my je bezpośrednio wywoływać (nieko- nas przycisków są obiektami klasy QPush- czone z sygnałem clicked() odpowied-
niecznie wskutek wystąpienia zdarze- Button, która dziedziczy z QAbstractBut- nich przycisków (np. slot additiveOper-
nia). Naturalną koleją rzeczy jest ich łą- ton. Z tej drugiej dziedziczą również in- atorClicked() połączymy z sygnałem
czenie z sygnałami. Jeden sygnał mo- ne klasy przycisków, takie jak Q3Button, clicked() przycisku dodawania).
że być podpięty do wielu slotów, a jeden QCheckBox czy RadioButton. Sposób rozmieszczenia przycisków
slot – do wielu sygnałów. Co więcej, mo- Wyświetlaczem kalkulatora będzie reprezentujących cyfry przedstawia-
żemy łączyć sygnały między sobą. Bar- pole tekstowe – obiekt $display klasy my na Listingu 4. Korzystając z meto-
dzo ważne jest to, że w Qt klasa, któ- QLineEdit, która. reprezentuje pojedyn- dy addWidget() obiektu $this->main-
ra może korzystać z sygnałów i slotów, czą linię tekstu z możliwością edycji. Jak Layout() klasy QGridLayout, każdemu z
musi dziedziczyć po QObject. Więcej na w prawdziwym kalkulatorze, przy inicja- nich przypisujemy konkretną kolumnę i
ten temat możemy przeczytać w drugim cji tej klasy wpisujemy wartość 0 (ja- wers, np. equalButton (przycisk równa
tutorialu Qt. ko parametr wysłany do konstruktora). się) będzie miał położenie (5,5). Meto-
Przyjrzyjmy się jeszcze raz pro- Tekst zawarty w tym polu odczytamy da addWidget wymaga podania trzech
stemu przykładowi z Listingu 1, któ- korzystając z metody $display->text(), parametrów: obiektu (np. przycisku),
ry składa się wyłącznie z okna główne- zaś do wpisania go użyjemy metody wersu i kolumny. Dodatkowo, możemy
go i przycisku Quit powodującego za- setText(). zdefiniować dwa opcjonalne parame-
kończenie działania aplikacji. Wszystkie try: rowSpan i colSpan, które pozwalają
widgety dziedziczące z QWidget, w tym Definiowanie wyglądu na łączenie kilku wersów lub kolumn w
nasz przycisk QPushButton, wysyłają sy- (layoutu) okienka jedną, podobnie jak ma to miejsce w ta-
gnały przy wystąpieniu dowolnego wy- Zdefiniujmy teraz wygląd (layout) nasze- belach HTML-owych.
darzenia. W naszym przykładzie jest to go kalkulatora. Określa on sposób or-
sygnał clicked(), wysyłany przez przy- ganizacji widgetów w oknie. Podstawo- Przeciążenie metod
cisk, który klikniemy myszką. Więcej wą klasą służącą do definiowania lay- (overloading)
o sygnałach i slotach można przeczytać outu (menedżerem layoutu, ang. layout Powiedzieliśmy, że parametry rowSpan
w tutorialu 7 PHP-Qt. Do łączenia slo- manager)jest QLayout, z której dziedzi- i colSpan są opcjonalne. Przyciski w
tów z sygnałami służy metoda connect() czą inne, takie jak QHBoxLayout, QVBox- naszym kalkulatorze, poza backspace-
danego widgetu, np.: Layout czy QGridLayout. Główną zale- Button, clearButton () i clearAllBut-
tą menedżerów layoutu jest to, że auto- ton(), są dodawane do layoutu metodą
connect($quit,SIGNAL("clicked()"), matycznie rozmieszczają one elementy addWidget() jedynie z trzema parame-
$app,SLOT("quit()")) w oknie, wymagając od programisty je- trami (obiekt, wers i kolumna). Opcjo-
dynie podania podstawowych parame- nalność rowSpan i colSpan nie jest
Metody SLOT() i SIGNAL() są wymaga- trów (np. kolumny i wersu). osiągana przez przypisywanie im war-
ne, aby zdefiniować sloty i sygnały – bez W naszym kalkulatorze użyjemy tości domyślnych w deklaracji metody
ich użycia nie będzie to możliwe. Metody klasy QGridLayout, która traktuje okno addWidget(), tylko przez przeciążenie
te odpowiadają makrom SIGNAL i SLOT aplikacji jako siatkę (ang. grid) podzie- (ang. overloading) tej metody. Parame-
z Qt dla C++. loną na wiersze i kolumny. Przyciski na- trem o wartości domyślnej jest nato-
Aby rozłączyć sloty i sygnały, mo- szego kalkulatora są pogrupowane wg miast Alignment, ustawiony standardo-
żemy użyć metody disconnect(), ale funkcji: operatory [[unary]], dodawania i wo na 0. Nagłówki metody addWidget()
przeważnie nie jest to wymagane, mnożenia, cyfry oraz inne (np. kasowa- z rowSpan i colSpan przetłumaczone na
gdyż Qt rozdziela je automatycznie w nie cyfr). Każda z grup ma po jednym PHP wyglądają następująco:
} ($widget, $row,
$column, $alignment = 0)
Na koniec nadajemy okienku tytuł PHP ton("")) i zwraca obiekt docelowy (tej stosowanie wobec wszystkich napi-
Solutions Calculator. samej klasy, co obiekt podany jako dru- sów, które chcemy wyświetlać. PHP-
gi parametr). Qt automatycznie konwertuje wszyst-
Zmiana typów (ang. type Następnie odczytujemy liczbę wpi- kie łańcuchy PHP na obiekty klasy
casting) saną przez użytkownika. W tym ce- QString.
Zobaczmy teraz, w jaki sposób klasa Cal- lu skorzystamy z metody text() kla- Większość metod Qt również zwra-
culator odnajduje przycisk wciśnięty sy obiektu $display (naszego wyświe- ca łańcuchy tego typu. Korzystanie
przez użytkownika. W tym celu przyjrzy- tlacza). Otrzymany rezultat będzie ty- z QString daje wiele rozmaitych moż-
my się metodzie unaryOperatorClicked() pu QString, a my potrzebujemy liczby, liwości manipulacji łańcuchami, takich
(Listing 5). na której będziemy mogli wykonywać jak ich liczenie, łączenie, zastępowa-
Do określenia, który przycisk zo- działania. Przekonwertujemy więc łań- nie, kasowanie, dzielenie czy konwer-
stał wciśnięty służy metoda sender() cuch na liczbę przy użyciu metody to- sja standardów (ASCII/Unicode/UTF8/
– zwraca ona obiekt, który wysłał sy- Double(): jeśli konwersja się nie powie- UTF16/Latin1 oraz typy numeryczne i
gnał. Metoda ta należy do klasy QOb- dzie, wynikiem będzie 0.0 i wywołana niektóre operatory). Wszystkie łańcu-
ject (z której dziedziczy każdy wid- zostanie metoda abortOperation() kla- chy przechowywane w Qt są domyśl-
get, również przycisk), a dostęp do sy Calculator. nie typu Unicode: stosowanie tego ty-
niej jest możliwy dzięki $this. Widzimy pu wobec łańcuchów podawanych jako
już, dlaczego klasa Calculator dzie- QString: obsługa parametry metod gwarantuje, że będą
dziczy z QDialog, która z kolei jest kla- łańcuchów w Qt wyświetlane poprawnie.
są pochodną wobec QObject. Dokład- Przyjrzyjmy się teraz możliwościom
niejsze informacje na temat dziedzicze- Qt w dziedzinie łańcuchów. Biblioteka Podsumowanie
nia klas w Qt znajdują się pod adresem ta oferuje szerokie możliwości obsłu- Zademonstrowaliśmy podstawowe moż-
http://www.trolltech.com/products /qt/ gi standardu unicode, łańcuchów i po- liwości PHP-Qt i na ich podstawie moż-
learnmore/classchart/. jedynczych znaków. Ułatwia też kon- na ocenić, że rozwój tej biblioteki zmierza
No dobrze, ale metoda sender() wersję typów znaków oraz internacjo- w dobrym kierunku.
zwraca obiekt klasy QObject, a nam nalizację. Obecnie, twórcy tego pakietu zaj-
jest potrzebny przycisk. Użyjemy więc Na Listingu 5 korzystamy z meto- mują się integracją ze SMOKE (któ-
funkcji qobject _ cast(), która zamie- dy tr(), która należy do klasy QObject ry zostanie użyty w następnych wer-
ni obiekt typu QObject na takowy. Wy- i klas pochodnych wobec niej. Zwra- sjach PHP-Qt i jest dołączony w obec-
maga ona podania dwóch parametrów: ca ona tłumaczenie podanego łańcu- nym wydaniu tego pakietu; jego celem
istniejącego obiektu oraz nowej, anoni- cha lub ten sam łańcuch, jeżeli nie ma jest utworzenie powiązań (ang. bin-
mowej instancji (w tym przypadku But- dla niego tłumaczenia. Zaleca się jej dings) pomiędzy PHP a Qt/KDE) oraz
przenosinami PHP-Qt do działające-
Listing 5. Zastosowanie metod qobject_cast i tr() klasy QObject go w systemie Subversion repozyto-
rium KDE.
function unaryOperatorClicked()
Nic więc nie stoi na przeszkodzie,
{
$clickedButton = qobject_cast($this->sender(), new Button(""));
aby wprowadzić do PHP-Qt pozostałe
$clickedOperator = $clickedButton->text(); klasy należące do Qt i KDE. Co wię-
$operand = $this->display->text()->toDouble(); cej, PHP-Qt ma być dostępne nieza-
$result; leżnie od KDE i nie wymagać żadnych
pakietów oprócz parsera PHP i biblio-
if ($clickedOperator->toAscii() == $this->tr("Sqrt")->toAscii()) {
if ($operand < 0.0) {
teki Qt. Lista mailingowa i repozyto-
$this->abortOperation(); rium Subversion pozwalają natomiast
return; śledzić rozwój pakietu PHP-Qt, który z
} każdą wersją staje się coraz lepszy. n
$result = sqrt($operand);
} else if ($clickedOperator->toAscii()==$this->tr("x\262")->toAscii()) {
$result = pow($operand, 2.0);
O autorze
} else if ($clickedOperator->toAscii()==$this->tr("1/x")->toAscii()) {
if ($operand == 0.0) { Thomas Mönicke studiuje informa-
$this->abortOperation(); tykę na Politechnice Brandenburskiej
return; w Cottbus. Jest autorem biblioteki PHP-
} Qt. Tworzy aplikacje GIS- i webowe dla
$result = 1.0 / $operand; Niemieckiego Instytutu Archeologiczne-
} go, a także pracuje nad systemem P2P
do widekonferencji o nazwie BRAVIS.
$this->display->setText(QString::number($result));
$this->waitingForOperand = true; Kontakt z autorem:
} thomas.moenicke@kdemail.net
M
ożemy też wypróbować też Rozwój
SMF jak wiele innych skryp- Bieżąca stabilna wersja to 1.2.14 a ko-
tów. Co jednak mamy zro- lejne wydania z tej serii ukażą się wy-
bić gdy chcemy lekkie, funkcjonalne łącznie w przypadku odkrycia błędów
i proste w zarządzaniu forum? Roz- lub luk bezpieczeństwa. Aktualizacje
wiązaniem jest punBB, skrypt rozwi- bezpieczeństwa ukazują się nie póź-
jany od 2003 roku przez Rickarda An- niej niż 48 godzin od zgłoszenia. Infor-
derssona. PunBB korzysta z bazy da- macje o odkrytych błędach i konieczno-
nych, do wyboru może to być MySQL, ści aktualizacji są podawane na stronie
W SIECI PostgreSQL lub SQLite. Skrypt mo- projektu oraz na specjalnej liście dys-
że działać zarówno pod PHP z serii kusyjnej.
4.3 jaki i PHP5. Instalacja skryptu jest Obecnie trwają prace nad punBB
1. http://www.punbb.org
– Strona punBB; bardzo prosta. 1.3, nową wersją rozwojową, która wpro-
2. http://www.punres.org Wystarczy pobrać archiwum ze stro- wadzi nowe funkcjonalności takie jak:
– Strona z modyfikacjami
i skórkami;
ny projektu, rozpakować i przenieść na
3. http://punbb.tox.pl nasz serwer i otworzyć w przeglądarce
– Polskie Wsparcie punBB; plik install.php. Pojawi się prosty, intu- Co obiecujemy:
4. http://www.tibiaswe.com/foru Poznasz podstawy PHP i HTML.
– Jedno z największych for icyjny instalator. Jeżeli chcemy prowa-
dyskusyjnych opartych o dzić forum w języku innym niż angielski
punBB;
to wystarczy pobrać ze strony punBB Co powinieneś wiedzieć:
5. http://www.phpclasses.org/ Umiejętność integrowania punBB z ze-
browse/package/2765.html odpowiedni pakiet językowy i umieścić wnętrznymi skryptami a także umiejęt-
– Forum Integrator, klasa
ułatwiające integrację punBB
go w katalogu lang a następnie ustawić ność migracji danych z innych skryptów
i phpBB; go domyślnym w panelu admina i profilu forum.
administratora.
l
łatwy w zarządzaniu system rozsze- nuksa (Gentoo). Każdy z testowych skryp- szerzony system użytkowników i upraw-
rzeń (tzw. Wtyczek); tów posiadał dwie kategorie oraz jeden te- nień obecnych w konkurencyjnych roz-
l
przyjazne linki dla wyszukiwarek; mat z jedną odpowiedzią. W celu otrzyma- wiązaniach.
l
usprawniony interfejs forum. nia powtarzalnych wyników autor wyko-
rzystał funkcję xdebug_peak_memory_usage Wdrożenia
Pierwsza stabilne wydanie z tej serii prze- w celu pomiaru maksymalnego zużycia PunBB mimo iż w sieci nie jest powszech-
widziane jest jeszcze na bieżący rok. pamięci przez wykonujący się kod forum nie znane zostało wdrożone w wielu ser-
dyskusyjnego. Wyniki zestawione są po- wisach. TibiaSwe to jedno z największych
Możliwości forum niżej. for opartych o ten skrypt mogące poszczy-
Tabela 1 prezentuje dostępne jaki brakują- Maksymalne zużycie pamięci: cić się ponad 320 tysiącami postów. Fo-
ce względem innych skryptów funkcjonal- rummatrix – serwis zajmujący się porów-
ności punBB. Zestawienie pochodzi z da- l
punBB (1.2.10): 0,742095 MB; nywaniem różnych skryptów tego typu ja-
nych serwisu forummatrix.org. l
phpBB (2.0): 1,699279 MB; ko forum dostępne w serwisie dla użyt-
l
IPB (2.0): 3,683769 MB; kowników również wybrał punBB. Twórcy
Wydajność l
SMF (1.1 RC 2): 3,769836 MB. tego serwisu wybrali punBB ze względu
Autor artykułu przeprowadził proste testy na system użytkowników i uprawnień, któ-
wydajnościowe z wykorzystaniem profilera Bardzo dobre wyniki punBB można czę- ry bardzo łatwo wykorzystać w zewnętrz-
Xdebug (wersja 2.0.0 beta 5) pracującego ściowo uzasadnić brakiem komponentów nych skryptach oraz jest łatwy w zarzą-
z PHP 5.1.2 pod kontrolą 64 bitowego li- takich jak prywatne wiadomości czy roz- dzaniu od strony forum.
INTEGRACJE
W łatwy sposób możemy uzyskać dostęp
do systemu użytkowników oraz bazy da-
nych (bieżącego połączenia). W tej kwestii
IPB z projektem IPB SDK jest nie do po-
Rysunek 1. Strona spinkBB - generatora arkuszy CSS dla punBB bicia, ale mimo to możliwości punBB oka-
PUNBB I COPPERMINE
GALLERY
CPG to skrypt galerii internetowej rozpro-
wadzanej na licencji GNU GPL. Na jego
przykładzie zaprezentujemy jak dokonać
prostej integracji skryptu z forum punBB
za pomocą klasy Forums Integrator. Lo-
gowanie, wylogowanie i rejestracja w na-
szej coppermine gallery wywoła identycz-
ny efekt na naszym forum punBB. Rysunek 2. Prosty interfejs importera danych
"(user_regdate, user_active,
user_actkey, user_name, Listing 3. Formularz logowania z przekierowaniem
user_password, user_email,
<form id="login" method="post" action="'.PUN_ROOT.'login.php?action=in"
user_profile1, onsubmit="return process_form(this)">
user_profile2, user_profile3, <input type="hidden" name="form_sent" value="1" />
user_profile4, <input type="hidden" name="redirect_url" value="'.
user_profile5, user_profile6) ". $_SERVER['SCRIPT_NAME'].'" />
<B>Login</B><BR />
"VALUES (NOW(), '$active',
<input type="text" name="req_username" size="15" maxlength="25"
'$act_key', /><BR /><BR />
'" . addslashes($user_name) . "', '" . <B>Password</B><BR />
addslashes($encpassword) . "', '" . <input type="password" name="req_password" size="15" maxlength=
addslashes($email) . "', '$profile1', "16" /><BR /><BR />
<input type="submit" name="login" value="Login" />
'$profile2', '$profile3', '$profile4',
</form>
'$profile5', '$profile6')";
Poniżej dodajemy: global $CONFIG, $db, do funkcji (czy klasy) obiektu klasy inte-
$pun_config, $pun_user; grującej jako argumentu.
include 'punbb.php'; //, $PHP_SELF;
$pun = new punbb('/ścieżka/do MIGRACJA FORUM:
/punbb/'); Integracja gotowa, operacje logowania, jakilinux.org
eval($pun->set_define()); wylogowania i rejestracji wykonają te sa- Administratorzy serwisu jakilinux.org po-
$pun->set_variables($pun_user, me operacje w punBB automatycznie. By stanowili rozpocząć migrację forum opar-
$pun_config); systemy użytkowników pozostały zsyn- tego o skrypt phpBB by Przemo. Obecnie
$pun->register($user_name, chronizowane zmieniamy lub usuwamy forum zawiera ponad 4000 postów i 500
$password, $email); odnośniki rejestracji i logowania na fo- użytkowników. Autor serwisu, Borys Mu-
rum na te z CPG. sielak tak uzasadnia podjętą decyzję:
Wyszukujemy: W powyższym kodzie użyliśmy „Plusem phpBB jest spora liczba
trzech metod klasy punBB – login, funkcji i popularność. Niestety, system
function check_user_info(&$error) logout i register, umieszczając wywoła- ten zupełnie nie sprawdza się, gdy wy-
{ nie tych metod w miejscach, w których magana jest jakakolwiek elastyczność.
global $CONFIG; //, $PHP_SELF; Coppermine Gallery wykonuje te sa- Kod phpBB jest trudny w modyfikacji
me operacje. Ostatnia zmiana, dodanie – system zaprojektowany został z uży-
I zastępujemy: trzech zmiennych punBB jako global- ciem przestarzałych metod (dotyczy to
nych była konieczna by wykorzystywa- zarówno rdzenia aplikacji jak i części od-
function check_user_info(&$error) ne elementy punBB działały poprawnie. powiedzialnej za wygląd). W odróżnieniu,
{ Innym rozwiązaniem byłoby przekazanie kod punBB napisany jest w sposób przej-
R E K L A M A
KONIEC
Niniejszy artykuł zaprezentował możliwości,
zalety i wady punBB. Zachęcam wszystkich
do sprawdzenia tej aplikacji w swoich roz-
wiązaniach. n
O autorze
Piotr Maliński jest studentem Politech-
niki Warszawskiej na kierunku Techno-
logia Chemiczna. Od czterech lat zaj-
muje się tworzeniem aplikacji w PHP jak
i od niedawna w Pythonie. Jest również
autorem serwisów o nazwie „Biblioteka
Riklaunima”.
Kontakt: riklaunim@gmail.com
Rysunek 3. Forum jakilinux.org po migracji danych prezentujące dwie skórki punBB
A
JAX to podejście do tworzenia wolucją jest tu bowiem fakt, że zmiany w
aplikacji internetowych polegają- aplikacjach internetowych Google doko-
ce na połączeniu możliwości ist- nują się nieomal w czasie rzeczywistym.
niejących już technologii w nową jakość. Wszystko to właśnie dzięki AJAX.
Termin AJAX użył po raz pierwszy Jes-
se James Garrett w swoim artykule pt. Źródła inspiracji?
„Ajax: A New Approach to Web Applica- Od strony użytkownika korzyści są wi-
tions” opublikowanym na początku roku doczne gołym okiem. Dla zwykłego in-
2005. Jego tekst był próbą odpowiedze- ternauty witryna wykorzystująca AJAX
W SIECI nia na pytanie, które wówczas zadawa- to strona, która niekoniecznie musi się
ło wiele ludzi, niekoniecznie profesjonal- przeładować by zmienić swoją zawar-
nie związanych z tworzeniem stron www. tość. W taki sposób można najkrócej
1. http://www.xajaxproject.org/
– strona główna projektu Pytanie to brzmiało i brzmi nadal – czym wyjaśnić ideę AJAX. Niestety, rozumo-
XAJAX. jest ta rewolucyjna technologia wprowa-
2. http://wiki.xajaxproject.org/
– dokumentacja wiki do pro-
dzona przez Google?
jektu. Z perspektywy czasu można powie- Powinieneś wiedzieć:
3. http://adaptivepath.com/ dzieć, że to właśnie Google zapoczątko- Wymagana jest dobra znajomość PHP
publications/essays/ oraz nabyte pewne podstawowe umiejęt-
archives/000385.php wało światowy boom na AJAX, prezentu-
– artykuł Ajax: A New Appro-
ności posługiwania się JavaScript.
jąc przełomowe na dzień dzisiejszy pro-
ach to Web Applications.
dukty. Aplikacje internetowe zaoferowane
4. http://developer.mozilla.org/
pl/docs/AJAX przez Google charakteryzują się ponad-
Obiecujemy:
– więcej informacji o samej
Szybki start w tworzeniu stron opartych o
technice AJAX na stronach
przeciętnymi wartościami użytkowymi, AJAX. Szybkie wdrażanie nowych pomy-
Mozilla Developer Center. ale to co je wyróżnia od innych, to wyso- słów dzięki XAJAX.
ki stopień interakcji z użytkownikiem. Re-
wanie wyłącznie w kontekście same- kacja, tkwiąc uwięziona w przeglądar- cy do miana internetowego Worda. In-
go AJAX-a nie daje prawdziwego obra- ce internetowej? Odpowiedź jest dość ne duże korporacje internetowe też nie
zu zastosowania tej techniki. Najlepiej prosta – działa, i to wcale nie najgo- próżnują. Yahoo ze swoim serwisem
więc zasięgnąć przykładów, kierując się rzej. Czy już czas zmienić swoje przy- zdjęciowym Flickr (http://www.flickr.com)
w stronę działających aplikacji Google. zwyczajenia i pisać dokumenty w edy- także aktywnie wykorzystuje możliwości
Rysunek 1 prezentuje aplikację Google torze tekstu umieszczonym na stronie AJAX. Choćby obracanie zdjęć bez ko-
Spreadsheets (http://spreadsheets.goog www? Rysunek 2 to przykład aplikacji nieczności przeładowania to tylko jed-
le.com), która nie tylko wyglądem, lecz i internetowej niemal żywcem przeniesio- na z robiących wrażenie na użytkowni-
funkcjonalnością przypomina typowy ar- nej z pakietu biurowego. Writely (http:// kach funkcji.
kusz kalkulacyjny. Co więc robi ta apli- writely.com) to produkt Google aspirują-
Jak to działa?
AJAX (ang. Asynchronous JavaScript and
XML) wykorzystuje do pracy komplet ist-
niejących technologii. Najczęściej do stwo-
rzenia aplikacji AJAX wykorzystuje się ta-
ki zestaw:
• HTML/XHTML – odpowiedzialny za
budowę struktury strony www.;
• CSS – oprawa graficzna witryny;
• JavaScript – realizacja żądań po
stronie klienta (wysyłanie/pobieranie/
przetwarzanie w ograniczonym stop-
niu);
• DOM – obiektowy dostęp do struktury
dokumentu (X)HTML;
• XML – pełniący tu rolę protokołu trans-
portowego (do wymiany pakietów da-
nych);
• PHP (lub dowolny inny język skryp-
towy: ASP/JSP/Ruby) – realizacja
żądań po stronie serwera (wysyłanie/
odbieranie danych/przetwarzanie da-
Rysunek 1. Google Spreadsheets, internetowy arkusz kalkulacyjny
nych ograniczone przez możliwości
serwera), głównie obejmuje wymianę
informacji z bazą danych (np. Postgre-
SQL, MySQL, SQLite);
• XMLHttpRequest – interfejs dzięki któ-
remu możliwe jest wysłanie i odbiera-
nie danych przez przeglądarkę w cza-
sie rzeczywistym (bez konieczności
przeładowania strony).
XAJAX
XAJAX to biblioteka udostępniana w for-
mie klasy PHP. Oparta o otwarty kod źró-
dłowy udostępniana jest na licencji LGPL.
Oznacza to, iż można na niej opierać apli-
kacje, za które dostaniemy zapłatę.
Jak to działa? XAJAX składa się z
dwóch bibliotek – napisanej w PHP oraz
napisanej w JavaScript. Każda z nich
przyjmuje na siebie część zadań. Biblio-
teka XAJAX pracująca w formie obiektu
PHP dla każdej funkcji PHP (która ma
mieć możliwość asynchronicznej wy- Rysunek 8. Wygląd gotowego systemu dodawania do obserwowanych
Script, która zrealizuje bardziej za- nie obserwujemy migania charaktery- dzie UTF-8. To zapewnia poprawną
awansowane zadanie (np. wyśle stycznego dla aplikacji XAJAX opar- obsługę narodowych znaków diak-
formularz, gdy ten zostanie spraw- tych o model synchroniczny; trycznych;
dzony przez AJAX na obecność • Dla każdej z funkcji PHP może zostać • XAJAX bardzo łatwo integruje się z
błędów); przypisana inna metoda obsługi (POST wszelkimi systemami szablonowymi.
• XAJAX porównuje dane, które mają lub GET). To pozwala zwiększyć nieco Od strony systemu szablonowego ko-
zostać uaktualnione na stronie, z tymi, bezpieczeństwo całej aplikacji i zapo- nieczne jest dodanie wyłącznie jednej
które już w danym miejscu się znajdu- biega przypadkowym błędom; zmiennej. W jej miejsce zostaną wy-
ją. Jeżeli nic nie ulega zmianie, xajax • Dane przesyłane pomiędzy klientem generowane odwołania do skryptów
nie podejmuje działań. W ten sposób a serwerem są kodowane w standar- JavaScript odpowiedzialnych za reali-
zację żądań;
• XAJAX w bardzo dobry sposób ra-
Listing 1. Kod źródłowy systemu zakładek
dzi sobie z wszelkimi skryptami Java-
<?php Script. Kod źródłowy strony przed i po
require('lib/xajax.inc.php'); wprowadzeniu tej biblioteki w życie nie
function tabarea($tabId) {
różni się znacząco.
sleep(1);
$objResponse = new xajaxResponse();
for($x=1; $x<=6; $x++) { Instalacja XAJAX
$x == $tabId ? $className = 'active' : $className = ''; Zadaniem tego artykułu jest zaprezento-
$objResponse->addScript("document.getElementById('tab".$x."'). wanie praktycznych rozwiązań, które moż-
className='$className'");
na niemal od zaraz wdrożyć na własną
}
$objResponse->addAssign("maintabarea", "innerHTML", stronę. Zanim jednak przystąpimy do pro-
implode('', file('tpl/tab_content_'.$tabId.'.html'))); gramowania, warto zapoznać się ze struk-
return $objResponse->getXML(); turą biblioteki oraz dostępnymi metodami.
} XAJAX można pobrać ze stro-
$xajax = new xajax();
ny mieszącej się pod adresem: http://
$xajax->registerFunction('tabarea');
$xajax->processRequests(); www.xajaxproject.org/. Dokumentację do
?> projektu w formie wiki można odnaleźć
<html> pod adresem: http://wiki.xajaxproject.org/.
[..] Do prawidłowej implementacji XAJAX
<?=$xajax->printJavascript()?>
potrzebne są trzy pliki. Dwa z nich pracu-
</head>
<body> ją po stronie serwera. Są to następujące
<script type="text/javascript"><!-- skrypty PHP:
xajax.loadingFunction = function(){xajax.$('loading')
style.display='block';}; • xajax.inc.php – główna klasa biblio-
function hideLoadingMessage() { xajax.$('loading').
teki;
style.display='none'; }
xajax.doneLoadingFunction = hideLoadingMessage; • xajaxResponse.inc.php – klasa do ge-
// --></script> nerowania odpowiedzi;
<div class="content"> • Po stronie klienta pracuje jeden skrypt
<ul class="tabs" id="maintab"> JavaScript;
id="tab1" class="active"><a href="?show=
• xajax.js – klasa do obsługi żądań po
tab1" onclick="xajax_tabarea('1'); return false;">Tab 1</a></li>
<li id="tab2"><a href="?show=tab2" onclick= stronie klienta;
"xajax_tabarea('2'); return false;">Tab 2</a></li>
id="tab3"><a href="?show=tab3" onclick= Przyglądając się kodowi źródłowemu xa-
"xajax_tabarea('3'); return false;">Tab 3</a></li> jax.js łatwo zauważyć, iż został on po-
id="tab4"><a href="?show=tab4" onclick=
zbawiony biały znaków. Ze względu na
"xajax_tabarea('4'); return false;">Tab 4</a></li>
id="tab5"><a href="?show=tab5" onclick= utrudnienia w dokonywaniu zmian w takim
"xajax_tabarea('5'); return false;">Tab 5</a></li> skrypcie udostępniono wersję z typowym
id="tab6"><a href="?show=tab6" onclick= formatowaniem – xajax_uncompressed.js.
"xajax_tabarea('6'); return false;">Tab 6</a></li> Do późniejszej kompresji posłuży bibliote-
</ul>
ka xajaxCompress.php.
<div class="insider">
<div id="loading">Ładowanie...</div> Wymagania sprzętowe odnośnie bi-
<div id="maintabarea"> blioteki:
<? include('tpl/tab_content_1.html') ?>
</div> • Serwer Apache lub IIS (Windows XP/
</div>
2003);
</div>
</body> • PHP 4.3.x lub 5.x;
</html> • Przeglądarka IE 5.5, Firefox 1.0, Sa-
fari 1.3, Opera 8.5.
Opis podstawowych
Listing 2. Kod źródłowy systemu zakładek
metod
Zaletą biblioteki XAJAX jest możliwość <?php
bardzo szybkiego startu. Podczas co- mysql_connect('localhost', 'root', 'root');
mysql_select_db('test');
dziennej pracy z XAJAX wykorzystamy
require('lib/xajax.inc.php');
stosunkowo niewielką ilość metod, będą-
cych częścią dwóch klas PHP. Warto po- function fetchObserve($id) {
krótce nakreślić charakterystykę najważ- return @mysql_result(mysql_query('SELECT 1 FROM
niejszych z nich. obserwowane WHERE article_id = "'.$id.'"'), 0);
}
Klasa xajax (xajax.inc.php):
function checkObserve($id) {
if(fetchObserve($id))
• debugOn() / debugOff() – włącza /
wyłącza przydatny tryb usuwania błę- // zaprzestan obserwowania
dów;
return 'Nie obserwuj';
• registerFunction($nazwaFunkcji)
else
lub registerFunction(array($nazwa-
Funkcji, $nazwaKlasy, $nazwaMetody)) //rozpocznij obserwowanie
– rejestruje funkcję PHP, do której będzie
można odwołać się poprzez JavaScript; return 'Obserwuj';
}
• processRequests() – uruchamia silnik
function observe($id) {
odpowiedzialny za obsługę przycho-
dzących wywołań; if(fetchObserve($id))
• printJavascript() / getJavascript
– wyświetla / zwraca kod JavaScript, mysql_query('DELETE FROM obserwowane
WHERE article_id = "'.$id.'"');
który musi zostać umieszczony w sek-
cji head strony. else
stworzyć zakładki, do których dane są po- ich wszędzie tam, gdzie dojdzie do zmian sługi JavaScript strona pracowała w mia-
bierane dopiero w momencie kliknięcia na na stronie. Podstawowym kontenerem, do rę poprawnie. Stąd linki do kolejnych za-
nieaktywną zakładkę. którego trafia tekst jest maintabarea. Jak kładek posiadają parametry ?show=tabx.
Tworzenie systemu zakładek rozpo- łatwo zauważyć poprzedza go kontener Oczywiście z uwagi na brak miejsca, w
czynamy od zbudowania podstawowe- loading, który domyślnie jest schowanych. powyższym kodzie brakuje obsługi takiej
go kodu XHTML, składającego się z kilku W momencie, gdy XAJAX przystępuje do sytuacji.
kontenerów oraz listy punktowanej (druga załadowania nowej zawartości, pojawia Poszczególne funkcje w XAJAX wy-
połowa listingu 1). Przy użyciu stylów CSS się informując użytkownika o trwającym wołuje się stosując konstrukcję xajax_
dokonujemy zmiany wyglądu poszczegól- procesie ładowania. Bez takiej informacji NazawFunkcji (Parametry). Jak łatwo za-
nych elementów, tak, by przypominały za- użytkownik może poczuć się zdezorien- uważyć, ilość kodu JavaScript zastosowa-
kładki. XAJAX rozpoznaje elementy po ich towany. Dokument XHTML jest skonstru- nego w tym przykładzie jest znikoma. Za-
identyfikatorach, stąd istotne jest dodanie owany tak, by nawet po wyłączeniu ob- stosowany dodatkowy parametr przy wła-
ściwości onclik – return false powoduje, iż
przeglądarka nie podąża za linkiem (ele-
Listing 3. Kod źródłowy systemu logowania – część pracująca po stronie serwera
ment href). Parametr przekazywany do
<?php funkcji xajax_tabarea pozwala rozróżnić
mysql_connect('localhost', 'root', 'root'); poszczególne zakładki, które odczytamy z
mysql_select_db('test'); plików szablonowych.
define ('XAJAX_DEFAULT_CHAR_ENCODING',
Pierwsza połowa Listingu 1 zawie-
'ISO-8859-2');
require('lib/xajax.inc.php');
ra kompletny kod potrzebny do obsługi
wszystkich zdarzeń. Programowanie roz-
if($_SERVER['QUERY_STRING'] == 'wszystko_ok_loguj') { poczynamy od załadowania części biblio-
echo 'yeah! zalogowany'; teki XAJAX napisanej w PHP. Opuśćmy
na chwilę deklarację funkcji tabarea, by
return 0;
przyjrzeć się instancji klasy xajax miesz-
} czącej się zaraz poniżej. Wszystkie funk-
function loginform($d) { cje, które mają być zbierane przez bi-
$objResponse = new xajaxResponse(); bliotekę JavaScript xajax muszą zostać
$email = $d['aEmail'];
uprzednio zarejestrowane. Nazwa funk-
$pass = $d['aPass'];
cji jest oczywiście zgodna z nazwą wystę-
// pytam baze o istnienie loginu pującą w kodzie XHTML. Metoda proces-
sRequest() generuje odpowiedni kod Ja-
$data = @mysql_fetch_array(mysql_query vaScript, który jest odpowiedzialny za ob-
('SELECT email, password, registered FROM
sługę żądań. Skompletowany w ten spo-
uzytkownicy WHERE email="'.$email.'"'));
sób kod JS wrzucamy sekcji HEAD do-
if(!$email OR !$pass) kumentu XHTML, korzystając z funkcji
$out = 'Proszę podać e-mail i login.'; printJavascript(). Wynik działania tej
else { funkcji to dołączenie do strony części bi-
if($email != $data['email']) {
blioteki XAJAX napisanej w JavaScript.
$out = 'Konto o podanym adresie nie istnieje.';
} else {
Funkcja zwraca ponadto do kodu źródło-
if($pass != $data['password']) wego strony także wszystkie inne dane
$out = 'Hasło do konta jest nieprawidłowe.'; potrzebne bibliotece do obsługi żądań.
else { Ponieważ w systemie zakładek ma-
if($data['registered'] == '0')
my do czynienia wyłącznie z jedną funk-
$out = 'Użytkownik nie potwierdził rejestracji.';
else {
cją, do jej obsłużenia musimy odpowied-
$out = 'Proszę czekać. <b>Logowanie</b>...'; nio stworzyć jedną funkcję PHP. Nazwa
$objResponse->addScript('document.loginform.submit();'); tej funkcji musi być zgodna z zarejestro-
} waną nazwą oraz nazewnictwem używa-
}
nym w kodzie strony. Zawartość funk-
}
}
cji tabarea to już praca na zupełnie in-
$objResponse->addAssign("logblad", "innerHTML", $out); nej klasie. XajaxResponse odpowiada za
generowanie odpowiedzi dla klienta. Pa-
return $objResponse->getXML(); rametr wejściowy funkcji $tabId to liczba
z zakresu 1-6. W kolejnych plikach mie-
}
$xajax = new xajax();
szących się w katalogu tpl umieszczona
$xajax->registerFunction('loginform'); jest zawartość kolejnych zakładek. Oczy-
$xajax->processRequests(); wiście w tym miejscu można posłużyć
?> się bazą danych lub bardziej skompliko-
wanym skryptem do pobierania danych,
Logowanie ginform znajduje się metoda xajax.get- cie dołączenia biblioteki xajax.js do sekcji
Proces logowania na stronie www prze- FormValues, gdzie jej parametrem jest head strony. Pozostałe czynności związa-
biega szablonowo. Gdy użytkownik wy- identyfikator przypisany do formularza. ne z JS ograniczają się już tylko do two-
pełni formularz, ten wysyłany jest meto- To właśnie ta linijka jest esencją tego rzenia odwołań do funkcji PHP. XAJAX
dą POST do serwera – użytkownik jest lo- przykładu. Do funkcji loginform widocz- spisuje się dobrze, nawet gdy pod uwa-
gowany. Co się jednak dzieje, gdy wpisa- nej na Listingu 3 trafiają wszystkie dane gę wziąć kwestię obsługi rodzimych zna-
ny przez niego login lub hasło są niepra- wprowadzone przez użytkownika w for- ków diaktrycznych. Bibliotekę tą można
widłowe? Użytkownik trafi czas, otrzymu- mie tablicy asocjacyjnej $d. Na podsta- uznać za idealną dla wszystkich tych pro-
jąc komunikat o niepoprawnych danych wie danych, które wprowadził użytkow- gramistów PHP, którzy cenią sobie stałość
dopiero po przeładowaniu strony. Stwórz- nik pobieramy z bazy danych użytkowni- i przewidywalność środowiska programi-
my zatem system logowania, który po ków informacje. W tym przykładzie może stycznego jakim jest język PHP. Umiejęt-
wciśnięciu przycisku loguj sprawdzi po- rozpatrujemy zbyt dużą ilość przypadków nie napisany kod PHP do obsługi XAJAX
prawność wprowadzonych danych. Jeże- w których użytkownik popełnia błąd, lecz pozwala na bardzo szybkie zmiany, dzię-
li będą one poprawne, formularz zostanie ma to na celu pokazanie jak szybko i ła- ki czemu nakłady dodatkowej pracy przy
wysłany metodą POST, a użytkownik zo- two przekazać użytkownikowi informację usuwaniu usterek są minimalne. W arty-
stanie zalogowany. Jeżeli dane będą nie- o niepoprawnym wprowadzeniu danych. kule udało się pokazać tylko najpopular-
poprawne, użytkownik bez konieczności Dopiero, gdy informacje są w pełni po- niejsze metody oferowane przez bibliote-
przeładowania strony otrzyma informację prawne, następuje logowanie. Polega ki XAJAX. Więcej informacji o pozostałej
o niepoprawnym loginie, bądź haśle. Ten ono na wyświetleniu informacji proszę funkcjonalności biblioteki można znaleźć
sposób rozumowania zapewnia, że nawet czekać oraz uruchomieniu skryptu, który w dokumentacji. n
przy wyłączonej obsłudze AJAX użytkow- automatycznie wyśle formularz.
nik będzie mógł skorzystać z usługi.
W poprzednich przykładach pominę- Podsumowanie O autorze
liśmy kwestię kodowania. Problem nie XAJAX to biblioteka, która pozwala pro-
był zauważalny. By dane przesyłane z gramiście przejść od nauki do programo- Paweł Grzesiak jest projektantem wi-
serwera poprzez XAJAX miały popraw- wania po zaledwie kwadransie. Popraw- tryn internetowych z sześcioletnim do-
ne kodowanie, należy ustalić domyślny ne działanie oraz pełnia automatyzacja świadczeniem. Zajmuje się tworzeniem
rozbudowanych witryn w oparciu o sys-
standard kodowania. sprawia, iż implementacja technik opar-
tem CMS własnego autorstwa. Jest au-
Mechanizm działania tego przykładu tych o AJAX staje się nieskomplikowana torem ponad 50 publikacji w Magazynie
uwzględnia nową właściwość, a miano- i przez to osiągalna dla każdego. W XA- Internet, Internet Maker oraz phpSolu-
wicie pobieranie danych, które użytkow- JAX-ie urzeka nie tylko prostota i efektyw- tions. Obecnie pracuje nad książką, która
ukaże się nakładem wydawnictwa Helion
nik wprowadził do formularza. Na koń- ność działania, lecz także mała inwazyj-
pod koniec tego roku.
cu Listingu 4 widoczne jest odwołanie do ność w kod już istniejących aplikacji. Przy-
skryptu JS odpowiedzialnego za obsłu- kładem na to jest kod JavaScript, o któ- Kontakt: pawel@grzesiak.com.pl
gę żądania. Wewnątrz funkcji xajax_lo- rym praktycznie zapomina się w momen-
R E K L A M A
I
stnieją techniki programistyczne uła- li istnieje taka potrzeba można przy je-
twiające tworzenie kodu, którego go pomocy powołać do życia instancję
prawie nie trzeba modyfikować w dowolnej klasy, wykonać publiczną me-
momencie, gdy pojawią się jakieś nowe todę dowolnego obiektu lub wykonać
wymagania. Wiele z tych technik opisy- dowolną funkcję. Reflection API bywa
wałem w poprzednich artykułach( Serwi- bardzo przydatnym narzędziem w każ-
ce Data Objects czyli uniwersalny stan- dej sytuacji, gdy z pewnych powodów
dard dostępu do danych cześć pierwsza podczas tworzenia kodu nie możemy
i druga, Wzorce projektowe w akcji czy- bezpośrednio wywołać jakieś metody
li czyli ciąg dalszy niezbędnika dewelo- lub funkcji. Na przykład dlatego, że nie
pera PHP, Zenda Framework,Budujemy znamy jej nazwy lub listy parametrów,
własny kontener IoC, czyli jak to się robi a wiemy, że poznamy je dopiero pod-
w Hollywood), w tym chciałbym się sku- czas wykonywania programu. Najczę-
pić na Reflection API i możliwościach ściej ma to miejsce w przypadku frame-
jego zastosowania w aplikacjach webo- worków gdzie nieznajomość klas i funk-
wych.
cji aplikacji zbudowanej na danym fra- publicznych metod sprawdzając dodat- ro w wersji 5.0. Zapewne dlatego jest ma-
meworku jest czymś naturalnym. Rza- kowo czy metoda istnieje i jest publiczna. ło znane. Od momentu swojego pojawie-
dziej można znaleźć zastosowanie dla Pełne opisanie czym jest Reflection API i nia się jest stale rozbudowywane o nowe
Reflection API w typowych aplikacjach. do czego można by je zastosować mo- klasy i metody. Dlatego jeżeli na prawdę
Aby lepiej je zrozumieć przyjrzyjcie się gło by zapewne stanowić pokaźny roz- będziecie chcieli korzystać z tego narzę-
prostemu przykładowi (Listing 1), w któ- dział jakiejś książce, dlatego nie oczekuj- dzia polecam używanie ostatniej stabilnej
rym front kontroler aplikacji ma za zada- cie, że zmieści się on w jednym artyku- wersji PHP jaka jest dostępna. Jeżeli nie
nie na podstawie zewnętrznych parame- le. Wszystkich zainteresowanych zazna- macie takich możliwości na stronach PHP
trów powołać do życia jakąś klasę i wy- jomieniem się ze szczegółami API od- znajdziecie dokładne informacje o tym,
wołać na niej metodę command z para- syłam do dokumentacji na stronie http:// które funkcjonalności API są dostępne w
metrami. www.php.net/manual/en/language.oop5. której wersji. Dodam, że cały kod napisa-
Oczywiście przykład ten nie pokazu- reflection.php. Znajdziecie tam też wiele ny na potrzeby tego artykułu był urucha-
je wszystkich możliwości Reflection API, przykładów pokazujących jak stosować miany w środowisku PHP 5.1.6 i niestety
pokazuje jednak sedno jego możliwości – Reflection API. nie wiem jak zachowa się we wcześniej-
powoływanie do życia dowolnych obiek- Reflection API jest stosunkowo świe- szych wersjach PHP.
tów i wywoływanie na nich dowolnych żym elementem PHP, pojawiło się dopie- Używając Reflection API należy pa-
miętać, że ma ono swoją cenę, jego uży-
cie może mieć wpływ na pogorszenie wy-
����� dajność całej aplikacji. Tak więc używajcie
������ ����� go z rozwagą. Na potrzeby tego artykułu
�������������� przeprowadziłem prosty test. Napisałem
������ � dwa kawałki kodu, w jednym na obiekcie
�
������ � wywoływałem metodę bezpośrednio, w
� ���� drugim przy pomocy Reflection API. Na-
�
�����
�
������ stępnie kod ten umieściłem w pętli for, któ-
�������
������ � ����� ra była wywoływana milion razy. Wynik nie
� �������� był zastraszający, okazało się że wywoły-
�
���������������� wanie bezpośrednie jest średnio dwa ra-
�����������������
�������������� zy szybsze. Jeżeli więc w kodzie aplikacji
�������������������� będzie niewiele wywołań tego typu, efekt
pogorszenia wydajności może być prawie
zauważalny.
Rysunek 1. Schemat procesu mapowania danych pochodzących z formularza na
obiekty biznesowe
Świat przed Reflection
API
Zanim powstało Reflection API, we
���� wcześniejszych wersjach PHP było wy-
posażone w kilka funkcji, które moż-
na by nazwać namiastką Reflection
��������
�������������������� ��������� API. Właściwe Reflection API zbiera te
����������������������� ������� wszystkie funkcje w jedną całość doda-
����������
jąc wiele nowych i udostępnia w posta-
ci zestawu klas. Ponadto w sam język
�������� ����� były i są ciągle wbudowane elementy
�������������������������� ��������� ������ przypominające swoim działanie Reflec-
�������������������������� ������� ����
�������������� ���������� ������� tion API. Na przykład porównując przy-
kład z front kontrolerem zamiast „$reflO-
bject->getInstance()” moglibyśmy od-
�������� ����� wołać się do możliwości PHP i ten sam
������������������ ��������� ������
������� ���� efekt uzyskać przy pomocy następują-
�������������������������
���������� ������� cego kodu „new $className()”, albo za-
miast metody invoke moglibyśmy zasto-
���� sować składnię „$object->{$methodName
($parameter)}. Podejście bez Reflection
API ma jednak dwa bardzo duże ograni-
Rysunek 2. Schemat blokowy algorytmu budowy obiektów biznesowych aplikacji czenia. Po pierwsze jest mniej elastycz-
z danych pochodzących z formularza, wraz z przykładowym przebiegiem ne gdyż wymaga dokładnej znajomości
ilości parametrów zarówno w przypadku Budowanie obiektów kasowany wszystko zależy od akcji po-
konstruktora jak i metody, którą chce- z requestu wiązanej z danym formularzem. Proces
my w ten sposób wywołać. Po drugie Spróbujmy teraz zdobytą wiedzę o Re- mapowania jest konieczny gdyż chcemy
w przypadku błędu PHP przerwie wyko- flection API wykorzystać do rozwiązania oddzielić funkcje biznesowe aplikacji od
nywanie kodu i zwróci Fatal Error, które- pewnego problemu. Wyobraźcie sobie, specyfiki warstwy prezentacji WWW. Wy-
go nie możemy kontrolować. Jeżeli za- że na wielu stronach waszej aplikacji wy- konywanie mapowania ręcznie jest bar-
stosujemy Reflection API każde niepo- stępuje formularz, za każdym razem in- dzo żmudnym zajęciem podczas, które-
wodzenie będzie sygnalizowane przy ny. Formularz ten w kodzie mapowany go może pojawić się wiele błędów. Do-
pomocy wyjątku, który możemy złapać jest do obiektu, a obiekt jest dalej wali- datkowo jeżeli, któryś z obiektów lub for-
i obsłużyć. dowany, zapisywany, modyfikowany lub mularzy ulegnie zmianie, mapowanie też
Listing 1. Implementacja prostej klasy front kontrolera, której przy pomocy Listing 2. Klasy biznesowe
Reflection API powoływane są obiekty klas akcji, a następnie na każdym z nich wykorzystywane w przykładzie. Ich
wywoływana jest metoda command charakterystyczną cechą jest to że
dostęp do ich atrybutów odbywa się
class FrontController { poprzez settery i gettery
public function doService
(HttpRequest $request){ class Group {
if ($request==null){ private $name;
return null; public
} function __construct() {
$className = $request-> }
getVar(); public function
$classObj = $this->create setName($name){
Object($className); $this->name = $name;
return $this->invoke }
Method($classObj,"command" public function getName(){
,$request); return $this->name;
} }
private function create }
Object($className){ class News {
if ($className==null){ private $title;
return null; private $author;
} private $date;
//Zakładamy że plik z klasą jest już załadowany private $content;
$relfObj = new public
ReflectionClass($className); function __construct() {
if (!$relfObj->isInstantiable()){ }
return null; public function setTitle
} ($title){
//Zakładamy że konstruktor $this->title = $title;
nie ma parametrów }
return $relfObj-> public function getTitle(){
newInstance(); return $this->title;
} }
private function invoke public function setAuthor
Method($object,$method ($author){
Name,$parameters){ $this->author = $author;
if ($object==null || $method }
Name==null){ public function getAuthor(){
return null; return $this->author;
} }
//Zakładamy że plik z klasą public function setDate($date){
jest już załadowany $this->date = $date;
$relfObj = new Reflection }
Object($object); public function getDate(){
return $this->date;
if (!$relfObj->hasMethod }
($methodName)){ public function setContent
return null; ($content){
} $this->content = $content;
return $relfObj->getMethod }
($methodName)->invoke public function getContent(){
($object,$parameters); return $this->content;
} }
} }
związanych z dostępem do atrybutów wszystkich metod w postaci obiektów ty- tu, na przykład bez problemu może-
obiektu poprzez settery i gettery. pu ReflectionMethod. Dla każdego obiek- cie dodać lub usunąć dowolne pole z
Cały kod metody bind przedstawiony tu ReflectionMethod sprawdzamy czy w obiektu newsa i kod bindera pozosta-
jest na Listingu 3. Jak widać nie jest dłu- requescie istnieje klucz odpowiadający nie bez zmian. Niestety nasz binder
gi. Na samym początku sprawdzamy czy nazwie settera. Jeżeli tak to przy pomocy ma jedną poważną wadę, nie obsługu-
parametry metody są poprawne, następ- metody invoke obiektu ReflectionMethod je ustawiania zmiennych na zagnież-
nie inicjalizujemy obiekt ReflectionObject, ustawiamy wartość spod tego klucza. dżonych obiektach. Co mam na myśli?
który zawiera metainformacje o naszym Metoda bind jest odporna na wiele Wyobraźcie sobie prosty przykład, ma-
obiekcie. Wydobywany z niego tablicę zmian związanych z zawartości obiek- my obiekt klasy Person (Listing 4) za-
wierający w sobie obiekt klast Address.
Listing 4a. Klasy biznesowe wykorzystywane w przykładzie Zakładając, że z requestu nie przycho-
dzą obiekty, a jedynie łańcuchy znako-
$this->firstName = $firstName; we nie możemy obsłużyć ustawienia
} atrybutów dla obiektu klasy Address.
public function getFistrName(){
Ich charakterystyczną cechą jest to że
return $this->firstName;
} dostęp do ich atrybutów odbywa się
public function setLastName($lastName){ poprzez settery i gettery.
$this->lastName = $lastName; Dodatkowo klasa Person w swoim
} konstruktorze inicjuje obiekt klasy Ad-
public function getLastName(){
drese dzięki temu metoda getAddress
return $this->lastName;
} zawsze zwróci obiekt Dlatego na ko-
public function setAddress($address){ lejnym listingu (Listing 5) umieszczo-
$this->address = $address; na jest wersja algorytmu, który roz-
} wiązuje ten problem. Do poprzednich
public function getAddress(){
dwóch założeń związanych z jego dzia-
return $this->address;
} łaniem dodałem jeszcze dwa. Pierw-
} sze, które mówi jak nazywać zmienne,
które są zagnieżdżone. Jeżeli chce-
Listing 5. Zawiera kod wersji metody bind umożliwiającej mapowanie my ustawić taką zmienną musimy po-
zagnieżdżonych obiektów
dać do niej pełną ścieżkę w posta-
class ComplexBinder { ci „obciętych” nazw getterów i sette-
public static function bind($request, $object){ rów oddzielonych kropkami. Na przy-
if($request==null || !is_array($request) || $object==null){ kład dla atrybutu street w obiekcie ad-
return null;
dress w requesie będzie musiał istnieć
}
//Tworzymy obiekt Reflection API
klucz address.street, co w normalnym
$reflectionObject = new ReflectionObject($object); odwołaniu w kodzie odpowiada nastę-
foreach($request as $attrName => $attrValue){ pującemu wywołaniu getAddress()-
//Zakładamy że możemy składać zagnieżdzone obiekty >setStreet($wartość). Drugie, któ-
$dotPosition = strpos($attrName,".");
re mówi że obiekty wewnętrzne mu-
if ($dotPosition===false){
//Jeżeli atrybut nie jest zagnieżdzony to sprawdzamy
szą być wstępnie inicjowane (tak jak
czy obiekt ma opowiedniego settera i ustawiamy ma to miejsce na listingu pokazującym
dla niego wartość obiekt Person (Listing 4)). To założenie
$setterName = "set".ucwords($attrName); wynika z faktu, że bez wstępnej inicja-
$setterObj = $reflectionObject->getMethod($setterName);
lizacji wywołanie kodu getAddress()-
if ($setterObj!=null && $setterObj->isPublic()){
>setStreet($wartość) nie powiodło-
$setterObj->invoke($object,$attrValue);
} by się bo getAddress zwróciłoby war-
} else { tość NULL.
//Jeżeli mamy doczynienia z zagnieżdzonym atrybutem Jak widać tym razem algorytm nie
to pobieramy ten atrybut i na nim ustawiamy odpowiednią wartość
jest już taki prosty. Ze względu na ko-
$getterName = "get".ucwords(substr($attrName,0,$dotPosition));
$getterObj = $reflectionObject->getMethod($getterName);
nieczność obsłużenia zagnieżdżonych
if ($getterObj!=null && $getterObj->isPublic()){ atrybutów zmieniliśmy sposób iteracji tym
$nestedObject = $getterObj->invoke($object); razem wykonujemy ją po każdym kluczu
self::bind(array(substr($attrName,$dotPosition+1) znajdującym się w requescie. Dla każdej
=>$attrValue),$nestedObject);
pary klucz, wartość z requesta sprawdza-
}
}
my czy w kluczu występuje kropka. Jeże-
} li nie to klucz traktujemy jako niezagnież-
} dżony atrybut i próbujemy ustawić odpo-
} wiadającą mu wartość na obiekcie. Jeże-
li obiekt jest zagnieżdżony, czyli posia-
dający w nazwie kropkę, to z części na- Tym razem nie będzie inaczej, ale jako, PHP. Możliwości zastosowania Reflec-
zwy przed pierwszą kropką tworzymy na- że przedstawiony do tej pory kod jest tion API można wymieniać długo. M.in.
zwę gettera i przy jego pomocy pobiera- oderwany od całości frameworku chciał- można budować formularze z obiektów,
my obiekt odpowiadający getterowi. Na- bym w kliku zdaniach napisać gdzie jest listy prezentujące dane, automatycznie
stępnie na tym obiekcie wywołujemy me- on umieszczony w Flexi. Metoda bind budować pytania zapisujące i modyfi-
todę bind. Zwróćcie uwagę, że w dzięki będzie częścią abstrakcyjnej klasy akcji, kujące dane w bazie. n
rekurencyjnemu wywołaniu metody bind dzięki czemu w każdej klasie akcji dzie-
nasz algorytm obsługuje dowolnie dłu- dziczącej po tym obiekcie programista
gie ścieżki. Może na przykład mieć struk- będzie mógł wywołać tą metodę. Do-
turę obiektów, której odpowiada ścieżka: datkowo jeżeli ktoś nie będzie chciał ko-
obiekt1.obiekt2.obiekt3.atrybut1. rzystać z abstrakcyjnej klasy akcji meto- O autorze
da będzie dostępne w klasie FLReflec- Piotr Szarwas ma wieloletnie doświad-
Flexi tionUtils. czenie w programowaniu i tworzeniu apli-
Mam nadzieje, że część z was śledzi kacji WWW (PHP, Java). Jest konsultan-
całą serię artykułów o wzorcach i do- Podsumowanie tem w jednej z największych polskich
firm IT, a także doktorantem na Wydzia-
brych praktykach programistyczny i wie Przedstawiony powyżej przykład jest le Fizyki Politechniki Warszawskiej. Od
że cały kod, który pojawia się w ramach tylko namiastką możliwości Reflecion dawna pisze artykuły dla PHP Solutions.
tych artykułów jest publikowany na sour- API. Mam jednak nadzieje, że udało mi
Kontakt z autorem:
ceforge pod szyldem frameworka o na- się zwrócić waszą uwagę na ten bar-
piotr.szarwas@gmail.com
zwie Flexi (http://flexi.sourceforge.net/). dzo pożyteczny moim zdaniem element
R E K L A M A
W
modelu tym istnieje tylko lach z warstwy danych. Warstwa serwi-
umowne podzielenie aplika- sów udostępnia zestawy funkcji pośred-
cji na części i hierarchię. Do- niczące między warstwą biznesową,
konywanie zmian w takim modelu jest a interfejsem użytkownika. Ostatnia war-
dość uciążliwe z powodu dużych powią- stwa – prezentacji – służy do wizualiza-
zań występujących wewnątrz kodu. Był cji danych, które zostały przetworzone
to podstawowy powód dla którego po- przez niższe warstwy modelu.
wstał model warstwowy. W tym artykule opiszę sposób imple-
mentacji aplikacji modelu warstwowego
Opis warstw modelu na przykładzie katalogu samochodowe-
Model będący przedmiotem niniejszego go, który następnie rozszerzę o kolejny
artykułu składa się z kilku warstw. Klu- obiekt – motocykl. Przed rozpoczęciem
czowym krokiem jest logiczne ich zdefi- omawiania modelu warstwowego na kon-
niowanie w stadium projektowania apli- kretnym przykładzie należy utworzyć ta-
kacji. Przykładowy i dość często stoso-
wany model składa się z czterech war-
stw(rysunek 1): dostępu do danych, biz-
Co obiecujemy:
Nowoczesne spojrzenie na tworzenie
nesowej, serwisów i interfejsu użytkow- średnich i dużych aplikacji. Sposób na
nika. W warstwie dostępu do danych proste zarządzanie kodem aplikacji.
powinny znajdować się modele (obiek-
ty, tablice asocjacyjne itp.), z których Co powinieneś wiedzieć:
będziemy korzystać w aplikacji. War- Zaawansowane techniki programowania.
Podstawy baz danych. Logiczne myśle-
stwa biznesowa to zbiór funkcji wyko-
nie w czasie procesu projektowania.
nujących określone zadania na mode-
Tabela 1. Warstwa dostępu do danych wywania (baza danych, pliki) powin- gdzie szukać/poprawiać/dodawać funk-
ny mieć swoje odzwierciedlenie mo- cje do konkretnych obiektów. Przykłado-
Presentation Layer
delowe w warstwie DAL. Przykładową wa implementacja warstwy BLL znajduje
Services Layer implementację warstwy DAL można się na Listingu 2.
zobaczyć na Listingu 1. Kod na listingu 2 zawiera kilka pod-
Business Logical Layer Plik zawiera definicję klasy Car. stawowych funkcji ułatwiających mani-
Nazwy składowych są takie same jak pulację obiektem i listą obiektów Car.
Data Access Layer
nazwy pól w bazie danych. Na tym Nazwy funkcji zostały dobrane zgodnie
belę, gdzie będą przechowywane dane etapie implementacji nie ma jeszcze z ich działaniem. Funkcja AddCar do-
samochodów. żadnych funkcji – są definiowane w daje obiekt do bazy danych, DeleteCar
warstwie BLL. usuwa z bazy, UpdateCar aktualizuje
CREATE TABLE Cars informacje, GetCarById odczytuje infor-
( Warstwa biznesowa macje o samochodzie o identyfikatorze
idCar INTEGER NOT NULL Celem tworzenia warstwy biznesowej idCar podanym w parametrze. Wszystkie
AUTO_INCREMENT, jest budowa zestawu funkcji używa- wymienione powyżej funkcje wykonują
model VARCHAR(25) NOT NULL, jących danych z warstwy DAL. Funk- operacje na pojedynczym obiekcie Car.
engineNumber VARCHAR(50) cje te powinny wykonywać podstawowe Jedyny wyjątek w klasie carManager sta-
NOT NULL, zadania, np. uzyskać konkretny obiekt, nowi funkcja GetCarList, która zwraca
wieght VARCHAR(16) NOT NULL, do którego odwołują się warstwy wyż- listę obiektów. Funkcja ta będzie następ-
color VARCHAR(20) NOT NULL, sze, uzyskać listę obiektów bądź wyko- nie używana do dostarczenia danych na
PRIMARY KEY(idCar) nać na obiekcie jakiekolwiek przekształ- potrzeby przeglądania wszystkich skata-
); cenie (edycję) zapisane następnie w wy- logowanych w bazie samochodów.
branej przez programistę formie. Do- Klasa carManager korzysta z klasy
Warstwa brym zwyczajem jest grupowanie od- sqlManager, która jest interfejsem po-
dostępu do danych powiednich funkcji w klasy managerów. średniczącym między aplikacją, a źró-
Warstwa dostępu do danych (DAL – Przykładowo carManager będzie klasą dłem danych. Klasa sqlManager zosta-
Data Access Layer) to najniżej leżąca warstwy biznesowej zawierającą funk- ła zdefiniowana osobno, ponieważ jej
warstwa modelu. Zawiera ona obiek- cje odnoszące się do wszystkich opera- funkcje mogą być z powodzeniem użyte
ty reprezentujące dane wykorzystywa- cji na obiekcie Car. Dzięki takiemu roz- w innych klasach warstwy BLL, których
ne w programie. Wszystkie informacje, wiązaniu programista, bądź zespół pro- istnienie w obecnej fazie projektu nie zo-
nie zależnie od sposobu ich przecho- gramistów będzie odruchowo wiedział stało przewidziane.
Jak widać przedstawienie listy ska- dokonać. Aplikacja o charakterze mo- projekcie służącym za przykład wyko-
talogowanych samochodów jest dziecin- nolitycznym z pewnością będzie mno- rzystania modelu warstwowego zosta-
nie prostym zadaniem. Sprowadza się żyć pytania w stylu:„Dlaczego funk- ły pominięte aspekty bezpieczeństwa,
do stworzenia obiektu serwisu i wywoła- cja getCarById zwraca sformatowa- graficznej prezentacji danych, a funk-
nia jego metody getCarList. W efekcie w ny tekst HTML, a nie obiekt? I gdzie cjonalność katalogu przedstawia wie-
zmiennej carArray otrzymujemy listę sa- ona jest w ogóle zdefiniowana?!”. Na- le do życzenia. Jest to zamierzone
mochodów zapisanych w bazie danych. tomiast w przypadku aplikacji warstwo- działanie, mające na celu nie zaciem-
Efekt działania warstwy prezentacji widać wej zapewne od razu – nawet średnio- nianie głównego tematu artykułu. Po-
na Rysunku 2. zaawansowanemu programiście – rzu- wyższe aspekty zostały świadomie
ci się w oczy logiczne ułożenie całe- pominięte. n
Ewolucja aplikacji go projektu. W związku z czym, będzie
Projekty programistyczne często nie mu zdecydowanie łatwiej dodać nową
posiadają sztywno narzuconych granic funkcjonalność.
funkcjonalności. Jest to podyktowane
różnymi względami, niekoniecznie zro- Podsumowanie O autorze
zumiałymi przez zespół programistycz- Przedstawiony w tym artykule spo- Paweł Klimczyk jest pasjonatem tech-
ny. Z biznesowego punktu widzenia w sób modelowania aplikacji jest prze- nicznym. W kręgu głównych zaintere-
aplikacji, która posłużyła za przykład znaczony zdecydowanie dla aplikacji sować komputerowych znajduje się:
do tego artykułu przydałby się rów- średnich bądź dużych. Użycie mode- tworzenie aplikacji webowych (asp.net,
php), wszelakie aspekty bezpieczeń-
nież katalog innych środków transpor- lu warstwowego w aplikacjach mniej- stwa i administracja serwerowa syste-
tu, np. motocykli bądź rowerów. Oczy- szych można porównać do celowania mów Linux. Aktualnie pracuje w firmie o
wiście w każdym modelu aplikacji (np. z armaty do muchy, aczkolwiek należy globalnym zasięgu – TRW Automotive –
warstwowym lub monolitycznym) jest w fazie projektu przemyśleć, czy cza- na stanowisku programisty i rozwija apli-
kacje wewnętrzne firmy.
możliwość dodania takiej funkcjonal- sem mały z pozoru projekt nie nosi
ności. Kluczowym aspektem jest tutaj znamion większego serwisu. Uważny Kontakt z autorem: pawel@klimczyk.pl
czas, w jakim programista może tego czytelnik z pewnością zauważył, że w
R E K L A M A
LIZ DB
– zaawansowane możliwości bazy MySQL 5
Stopień trudności: lll
Łukasz Budnik
W
PHP5 nie ma jeszcze odpo- wersji PHP4. Głównie z powodu używa-
wiedniego modułu, który by nia zaawansowanej obiektowych, in-
umożliwiał pracę z nowymi terfejsów oraz mechanizmu wyjątków
opcjami bazy MySQL 5. Tak – możemy dla sygnalizowania sytuacji nieprawi-
oprogramować wszystko samemu, tyl- dłowych i błędów. LIZ DB jest dostęp-
ko czy trzeba nam wymyślać ponownie nym na sourceforge.net. Możemy ścią-
koło? Czy wszystko musimy robić ręcz- gnąć najnowszą wersję kodów źródło-
nie? Oczywiście, że nie. Możemy sobie
ułatwić pracę korzystając z gotowej bi-
blioteki. Co obiecujemy:
Nauczysz się korzystać z zaawansowa-
LIZ DB – z wszystkiego nej biblioteki LIZ DB, dzięki niej nauczysz
się pisać szybko programy bazodanowe
po trochu: Java, .NET począwszy od prostych zapytań, zapy-
Podtytuł tego paragrafu może być dość tań przygotowanych a skończywszy na
mylący. Pewnie każdy z nas pomyślał, że wywołaniach procedur składowanych.
Zapoznasz się z nowymi możliwościa-
musi mieć PHP5 z mnóstwem dodatko-
mi MySQL 5, poznasz metody tworze-
wych modułów. Otóż nie – potrzebujemy nie składowanych procedur i funkcji oraz
oczywiście PHP5 z tylko jednym (z punk- dowiesz się jak i kiedy stosować je w
tu widzenia LIZ DB) modułem – MySQLi. praktyce.
Moduł ten wypiera starszą implementacje
MySQL w PHP i jest dostępny również w Co powinieneś wiedzieć:
Powinieneś mieć ogólną wiedzę z obiek-
wersji PHP4.
towości PHP5, powinieneś dobrze znać
LIZ DB jest narzędziem napisanym MySQL (nie koniecznie MySQL 5).
w PHP5 i nie będzie chodził na starszej
wych wraz z obszernymi przykłada- ków najważniejsze to, że powstał bardzo także składnie tworzenia takich proce-
mi ze strony głównej projektu: http:// dobry i o dużych możliwościach silnik do dur i funkcji.
sourceforge.net/projects/lizdb, dodatko- obsługi baz danych MySQL 5.
we informacje można znaleźć na stro- Po przeczytaniu tego artykułu LIZ DB – biblioteka
nie http://www.komputery-internet.net/ uzmysłowimy sobie, że zaawansowa- do obsługi MySQL 5
php/. ne możliwości baz danych wcale nie są LIZ DB to narzędzie napisane w nowym
Twórca tej biblioteki oprócz tego, że takie straszne jak by się mogło wyda- obiektowym PHP5. Jakie są jego możli-
jest programistą PHP jest również progra- wać i bez problemu możemy z nich ko- wości? Są spore! Oto najważniejsze:
mistą Java i MS .NET, w których również rzystać, nawet jeśli dopiero zaczynamy
oprogramowuje bazy danych. LIZ DB za- programować w PHP5. • pobieranie danych na różne sposoby
wiera parę zapożyczeń koncepcji z JDBC W ostatniej części tego artyku- – Select (zbiory rekordów), SelectOne
oraz .NET. ły omówimy jakie należy nadać prawa (pojedynczy rekord), SelectColumn
Można powiedzieć, że z każdej tech- użytkownikom MySQL aby móc two- (zbiór kolumn);
nologii wybrane zostało to, co najlepsze. rzyć, zamieniać i oczywiście wykony- • pełne wsparcie i wykonywanie in-
A co dla nas, jako końcowych użytkowni- wać procedury składowane. Omówimy strukcji DML (INSERT, UPDATE, DE-
LETE) oraz DDL (CREATE, ALTER,
CHANGE, DROP);
Nowe możliwości MySQL 5 • przygotowywanie i wykonywanie za-
pytań w stylu Java'y: setInt(1, $pa-
• Procedury i funkcje składowane (ang. Stored Procedures) – procedury i funkcje ram), setString(2, $param), setBlob(3,
umieszczane na serwerze, mogą wykonywać skomplikowane operacje, które z punktu
$param) etc.;
widzenia programisty sprowadzają się do wykonania jednej operacji – wywołania pro-
• zarządzanie i wspomaganie zaawan-
cedury, znacznie więcej na ten temat w artykule
• Wyzwalacze (ang. Triggers) – procedury wykonywane gdy zachodzą pewne zdarze- sowanych transakcji: commit, roll-
nia w bazie (np. wstawienie, edycja czy usunięcie rekordu) back, savepoint, rollback do założo-
• Widoki (and. Views) – mechanizm poprawiający bezpieczeństwo danych, jeśli ma- nych savepointów;
my tabelę pracownicy i nie chcemy aby każdy mógł ją przeglądać (np. kolumnę • przygotowywanie i wykonywanie
z płacami), wówczas tworzymy widok jako polecenie: CREATE VIEW „w _ pracownicy” procedur i funkcji składowanych
AS SELECT id _ p, imię, nazwisko, dział, pozycja, staż FROM pracownicy. Na- z pełną obsługą parametrów we
stępnie odbieramy prawa SELECT do tablicy pracownicy i nadajemy je do widoku wszystkich możliwych kierunkach:
„w _ pracownicy” IN, INOUT, OUT w stylu .NET;
• Bazę i schematy meta danych (ang. metadata, Information Schema) – w bazie • logowanie, na różnych poziomach,
information _ schema – znajdziemy informacje o bazie i jej schematach, znajdu-
wszystkich wykonywanych zapytań;
ją się tu np. definicje wyzwalaczy: obsługiwane zdarzenie, baza, tabela i ewentual-
ne kolumny do monitorowania i ciało wyzwalacza, definicje procedur i funkcji – tabe-
la ROUTINES, w której przechowywane są charakterystyki, informacje o bezpieczeń- LIZ DB definiuje interfejsy klas służących
stwie oraz oczywiście ciała procedur i funkcji do połączeń do bazy, zapytań przygoto-
• Możliwość dołączania i odłączania silników bazy na zasadzie pluginów, dodano tak- wywanych (ang. prepared statements),
że nowe silniki: archiwizacje (ang. Archive) – jest to silnik, który przechowuje dane w procedur składowanych i dostarcza ich
postaci skompresowanej dzięki czemu zajmują one mniej miejsca na dysku twardym implementację właśnie dla MySQL5.
oraz rozproszone (ang. Federated) – które umożliwiają stworzenie tablicy, która wi- Omówię po kolei każdy z interfejsów.
doczna jest dla użytkowników jako lokalna a w rzeczywistości przechowująca dane Spis interfejsów oraz klas ich implemen-
na innym serwerze tujących znajdziesz w ramce.
IDB – interfejs
Interfejsy i klasy LIZ DB połączenia do bazy
Implementacją tego interfejsu jest klasa
Interfejsy i ich implementacje: MySQLimp, znajduje się ona w katalogu
LIZDB/classes.
• IDB - definiuje 16 metod służących do obsługi transakcji, wykonywaniu instrukcji DDL,
DML, SELECT, definiuje również trzy poziomy logowania zapytań klasą implementują- Dostarcza ona podstawowej funk-
cą ten interfejs jest MySQLimp cjonalności związanej z pracą na bazie.
• IPreparedStatement - definiuje 8 metod służących do obsługi przygotowywanych za- Dzięki niej połączymy się z bazą danych
pytań, służące głównie do ustawiania wartości zapytania klasą implementującą ten i będziemy mogli wykonywać podstawo-
interfejs jest MySQLimpPreparedStatement we operacje na operacje, takie jakie wy-
• IStoredProcedure - definiuje 9 metod służących do obsługi składowanych procedur konujemy dziesiątki tysięcy dziennie.
i funkcji, interfejs ten definiuje także trzy typu kierunków parametrów: IN, INOUT oraz Ale od początku jak wygląda kod
OUT jak również typy: STORED _ PROCEDURE (dla procedur) STORED _ FUNCTION (dla PHP5 co musimy włączyć do nasze-
funkcji) klasą implementującą ten interfejs jest MySQLimpStoredProcedure
go skryptu aby móc rozpocząć pracę
z LIZ DB.
Przede wszystkim pobrać najnow- ci wyjątek z komunikatem, informującym dów które uległy zmianie, dla zapytań
szą wersję z sourceforge.net i rozpako- nas o właściwej metodzie jaką powinni- trupy DDL (CREATE/DROP) RunQuery
wać ją do swojego testowego katalogu. śmy użyć aby prawidłowo wykonać i ob- zwróci: prawdę jeśli operacja się powio-
Możemy od razu podejrzeć przykłady służyć wynik naszego zapytania. dła oraz fałsz jeśli wystąpił problem.
– są one w katalogu examples jest tam A wyniki mogą być różne np. dla za- Dla przykładowej tablicy, jaką mamy
także katalog sql, w którym znajdzie- pytań DML RunQuery zwróci odpowied- pokazaną na Listingu 1, za pomocą LIZ
cie wszystkie potrzebne definicje tabel nio dla: INSERT – ID wstawionego re- DB możemy wykonać podstawowe ope-
(wraz z przykładowymi rekordami) oraz kordu, UPDATE, DELETE – ilości rekor- racje pokazane na Listingu 2.
definicje procedur i funkcji składowa-
nych używanych w przykładach.
Spójrzmy jak powinien wyglądać Listing 1. Przykładowa tabela używana w artykule
skrypt PHP5 korzystający z LIZ DB: CREATE TABLE `lizdb_test_table` (
`id` mediumint(9) NOT NULL
define('LIZDB_PATH', '/home/xh/public_ auto_increment,
html/testy/ `char_column` varchar(255)
NOT NULL default '',
LIZDB');
`int_column` int(11) NOT NULL,
require LIZDB_PATH . '/classes/ `double_column` double NOT NULL,
MySQLimp.inc.php'; PRIMARY KEY (`id`)
// wstaw swoje dane kolejno: serwer, ) ENGINE=InnoDB
login, hasło oraz DEFAULT CHARSET=latin2;
I to wszystko, prawda, że proste? Dodat- sty, który w swoim kodzie będzie wykony- i później modyfikować funkcjonalność biz-
kowo przygotowanym zapytaniem mo- wał tylko jedną instrukcję SQL. nesową tylko w jednym miejscu – bazie
że być SELECT, wówczas $result będzie Kolejnym przykładem może być przy- danych.
zawierało zbiór tablic asocjacyjnych z re- kład dużej firmy – zakładu ubezpieczeń, Wszechwładny i okazać by się mogło
kordami. Wszystko jest automatycznie może firmy telekomunikacyjnej. Mamy wszystko posiadający phpMyAdmin nie
rozpoznawane i odpowiednio wykonywa- setki oddziałów, może miliony klientów. potrafi rozpoznawać i wykonywać proce-
ne przez LIZ DB – w przeciwieństwie do Działamy też w środowisku w którym bar- dur składowanych, my za pomocą LIZ DB
ręcznego wykonywania w PHP przedsta- dzo często zmienia się prawo czy profil będziemy w stanie wywołać każdą funkcję
wionego na listingu 4. usług. Każda zmiana przepisów wymu- czy procedurę składowaną, nawet jeśli do-
sza na nas pewne zmiany czy to w struk- piero zaczynamy naszą przygodę z PHP.
IStoredProcedure turze bazy danych czy też w samych za- Spójrzmy na przykładową funkcję
– interfejs do pytaniach. Musielibyśmy w takim razie składowaną i procedurę o wszystkich
wywoływania procedur i wykonywać co miesiąc setki (miliony?) możliwych kierunkach parametrów: IN,
funkcji składowanych aktualizacji oprogramowania użytkowni- INOUT, OUT – listing 5.
Jest to najważniejsza i najpotężniejsza ków końcowych – znacznie prościej zde- Nie jesteśmy pismem dla admini-
część całej biblioteki LIZ DB. Ale najpierw finiować interfejs procedury czy funkcji stratorów baz danych, ale dla porządku
odpowiedzmy sobie na pytania – co to są
tak na prawdę te procedury i gdzie znaj-
dują one swoje zastosowanie. Procedu- Listing 5. Definicje przykładowych procedur i funkcji składowanych
ry składowane są to fragmenty najczę- drop procedure if exists sayMyName;
ściej sparametryzowane i często używa- delimiter //
ne instrukcje SQL, które mogą wykony- CREATE PROCEDURE sayMyName
wać operacje aktualizacji lub tylko pobie- (OUT param1 INT, INOUT param2 CHAR(200),
IN param3 CHAR(100))
rania danych. Fragmenty procedur może-
BEGIN
my opakować np. w transakcje. SELECT COUNT(*) INTO param1 FROM
Procedury mogą przysłaniać przed `lizdb_test_table`;
końcowym użytkownikiem cały mecha- SET param2 = concat(param2, param3);
nizm swoich operacji, np. procedura, któ- END;
//
ra podaje średnie koszty, przychody ze
delimiter ;
sprzedaży, ukrywa w swoim wnętrzu ta- drop function if exists hello;
bele, z których pobiera dane, co więcej CREATE FUNCTION hello (s CHAR(20))
użytkownik wykonujący tę procedurę mo- RETURNS CHAR(50)
że nie mieć dostępu do pewnych zaso- RETURN CONCAT('Hello, ',s,'!');
Rysunek 1. Ręczne wykonanie procedur składowanych i funkcji w MySQL CREATE DEFINER = 'xh'@'%' PROCEDURE
simpleproc (OUT param1 INT) LANGUAGE SQL
DETERMINISTIC SQL SECURITY INVOKER
Listing 6. Wywoływanie składowanych funkcji i metod za pomocą biblioteki
NO SQL COMMENT 'ot taki komentarz'
LIZ DB
BEGIN
$call = $db->PrepareCall('sayMyName (?, ?, ?)', SELECT 123 INTO param1;
IStoredProcedure::STORED_PROCEDURE); END;
$parameter = array();
// przykład parametru INOUT
Nie uda się – jak napisaliśmy wcześniej
$parameter['type'] = IstoredProcedure:
:INOUT_PARAMETER; aby utworzyć procedurę z wartością
$parameter['value'] = 'testujemy parametry DEFINER inną niż bieżący użytkownik
wejściowe i wyjściowe'; – lizdb_user powinien posiadać przywi-
// możemy definiować parametry w dowolnej
lej SUPER.
kolejności, powyższy jest drugim parametrem
Zmodyfikujmy więc powyższy kod
$call->SetParameter(2, $parameter);
// parametr OUT wyjściowy i napiszmy tak:
$parameter['value'] = 'ta wartość jest nie istotna i tak
zostanie nadpisana'; CREATE DEFINER = CURRENT_USER
$parameter['type'] = IstoredProcedure:
PROCEDURE simpleproc (OUT param1 INT)
:OUT_PARAMETER;
LANGUAGE SQL DETERMINISTIC SQL
// to jest pierwszy paramter
$call->SetParameter(1, $parameter); SECURITY INVOKER NO SQL COMMENT
// standardowy typ IN 'ot taki komentarz'
$parameter['value'] = 'przyklej mnie do BEGIN
drugiego parametru!';
SELECT 123 INTO param1;
$parameter['type'] = IstoredProcedure:
END;
:IN_PARAMETER;
// ustaw jako trzeci parametr Lub w ogóle omijamy DEFINER = CURRENT_
$call->SetParameter(3, $parameter); USER
$db->ExecuteCall($call); ponieważ jest to domyślne zachowanie
$parameters = $call->GetParameters();
MySQL.
echo '<p>INOUT parametr (#2) ma wartość:
' . $parameters[2]['value'] . '</p>';
echo '<p>OUT parametr (#1) przypisano nową wartość: Jak w ogóle wykonać nasze procedury i
' . $parameters[1]['value'] . '</p>'; funkcje w MySQL? Utwórzmy procedury
// teraz wykonajmy funkcję składowaną i zalogujmy się do MySQL. Zakładamy,
// pierwszym argumentem jest ponownie szablon,
że pracujemy na bazie test:
drugim jest typ STORED_FUNCTION
$call = $db->PrepareCall('hello (?)', IstoredProcedure:
:STORED_FUNCTION); $ mysql -u root -p -D test < examples/
$parameter = array(); stored_
$parameter['type'] = IstoredProcedure: procedures.sql
:IN_PARAMETER;
$parameter['value'] = 'Łukaszu';
Zauważmy, że podałem tutaj parametr
$call->SetParameter(1, $parameter);
$result = $db->ExecuteCall($call); informujący do jakiej chcę się połączyć
echo '<p>Wynikiem wykonania funkcji bazy danych (-D test) – jest to ważne
hello(?) jest: ' . $result . '</p>'; ponieważ procedury utworzone w bazie
test będą widoczne tylko i wyłącznie w
obrębie tej bazy. Nie możemy utworzyć Spójrzmy na problemy z jakimi spo- $call = $db->PrepareCall
procedury globalnej, która będzie dzia- tkalibyśmy się gdybyśmy wykonywa- ('hello (?)',
łała we wszystkich bazach – procedury li wszystko ręcznie w PHP. Przede IstoredProcedure:
działają na konkretnych tabelach, w jed- wszystkim wiele problemów nastarczyło :STORED_FUNCTION);
nej konkretnej bazie. by nam samo oprogramowanie parame-
Następnie połączmy się do bazy i trów o kierunkach OUT czy INOUT. Mu- Markery ustawiamy analogicznie jak
utwórzmy użytkownika z takimi prawami: sielibyśmy wykonywać zawsze ustawie- w przypadku przygotowywanych zapytań:
nie zmiennych, potem musielibyśmy wy-
CREATE USER lizdb_user@localhost wołać procedurę i jeszcze raz zapytać $call->SetParameter
IDENTIFIED BY 'lizdb'; się o zmienne. W dodatku musielibyśmy (1, $parameter);
GRANT tak robić dla każdej naszej procedury co
SELECT, INSERT, UPDATE, DELETE, może być męczące. Z jedną różnica $parameter nie jest tutaj
CREATE, DROP, INDEX, ALTER, LIZ DB automatyzuje cały ten proces, zmienną skalarną reprezentującą kon-
CREATE ROUTINE, ALTER ROUTINE ci z was, którzy programowali w .NET za- kretną wartość a tablicą asocjacyjną,
EXECUTE uważą pewne analogie. Ale od początku która posiada dwa ważne pola:
ON `test`. * TO lizdb_user@localhost jak wykonujemy takie rzeczy w LIZ DB?
IDENTIFIED BY 'lizdb'; Mając już obiekt $db tworzymy obiekt im- $parameter['value'] =
plementują interfejs IStoredProcedure: 'tutaj podajemy wartość
Zauważymy od razu nowe opcje, które parametru';
nie są dostępne w MySQL4 (podałem je $call = $db->PrepareCal $parameter['type'] = IstoredProcedure:
w osobnej linii) są to: CREATE ROUTINE, l('sayMyName (?, ?, ?)', :IN_PARAMETER;
ALTER ROUTINE, EXECUTE – służące ko- IstoredProcedure:
lejno: do tworzenia, zmieniania oraz wy- :STORED_PROCEDURE); Typ decyduje o tym jak zostanie obsłużo-
konywania procedur i funkcji składowa- ny nasz parametr. Nie musimy ustawiać
nych. ROUTINE jest tu użyte jako słowo Pierwszym argumentem jest szablon na- wartości dla parametru typu OUT_PA-
klucz i zostało wprowadzone – aby nie szej procedury składowanej, drugim pa- RAMETER ponieważ cokolwiek podamy
nadawać osobno praw typu: CREATE rametrem jest typ – jak już wiemy inaczej zostanie i tak nadpisane. Jeśli ustawimy
PROCEDURE, CREATE FUNCTION. woła się funkcje a inaczej procedury. W już wszystkie pola naszej procedury wy-
Prze logujmy się na nowego użytkow- przypadku funkcji hello napisalibyśmy tak: konujemy ją bardzo prosto:
nika (do bazy test), którego przed chwilką
utworzyliśmy. Wywołanie funkcji wykonu- Listing 7. Najkrótsza i najprostsza wersja wywołania procedury getRecords()
je się w połączeniu z frazą SELECT – po- w MySQLi
nieważ chcemy „coś” pobrać – tu wynik
$mysqli = new mysqli('localhost', 'xh', 'secret', 'test');
działania funkcji. Piszemy następująco:
// musimy wykonać jako zapytanie typu MULTI
aby MySQL nie zerwał połączenia
mysql> SELECT hello ('Łukaszu'); // jeśli zajrzymy w kod LIZ DB zobaczymy, że tam
nie ma takich wybiegów,
Aby wywołać procedurę użyjemy in- // dodatkowo LIZ DB do wywołań procedur używa
wewnętrznie przygotowywanych zapytań
strukcji CALL, dodatkowo zauważmy,
// zauważmy, że gdybyśmy chcieli oprogramować
że gdy chcemy dostać odpowiedź od
samemu markery i przygotowywane zapytania
MySQL przez parametr nie możemy // jak w poprzednich przykładach,
podać wartości a zmienną! To się ty- najprawdopodobniej dodalibyśmy tu jeszcze kilka
czy jedynie parametrów o kierunkach // lini kodu obsługi do każdego takiego parametru
$mysqli->multi_query('CALL getRecords()');
OUT oraz INOUT. Dodatkowo parame-
// pobieramy rezulat
try INOUT jak widzimy posiadają war-
$result = $mysqli->store_result();
tość, którą wprowadzamy do procedu- // iterujemy po wynikach
ry a która jest wewnątrz modyfikowa- while ($row = $result->fetch_row()) {
na. Musimy więc do takiej zmiennej naj- // musimy znać ilość pól, ich nazwy
// LIZ DB automatycznie za nas to zrobi na
pierw przypisać wartość. Piszemy więc
podstawie meta danych
w konsoli MySQL:
$values['id'] = $row[0];
$values['char_column'] = $row[1];
mysql> set @zmienna = 'Do tego łańcucha $values['int_column'] = $row[2];
dokleję coś w procedurze...'; $values['double_column'] = $row[3];
$records[] = $values;
mysql> CALL sayMyName(@ileRekordow,
}
@zmienna, ' np. to dokleje ;)');
$result->close();
mysql> SELECT @zmienna, @ileRekordow; // końcowa odpowiedź
var_dump($records);
Wynik powyższych sekwencji instrukcji $mysqli->close();
SQL możemy zobaczyć na Rysunku 1.
Wielojęzyczna konfiguracja
stron z użyciem eZ publish
Stopień trudności: lll
Łukasz Serwatka
T
en artykuł opisuje, jak konfiguro- zainstalowanej jako moduł Apache'a
wać wielojęzyczne strony z uży- (mod_php). (Zwracamy uwagę, że eZ
ciem eZ publish, udostępniając publish nie działa z PHP w wersji 5).
stronę webową międzynarodowej grupie PHP musi mieć wbudowaną obsługę al-
użytkowników. eZ publish w wersji 3.8 bo MySQL 4.1 lub nowszego, albo Post-
zawiera wiele ulepszeń do swojego mo- greSQL 7.3 lub nowszego.
delu wielojęzycznej zawartości strony.
Te ulepszenia są opisane w specyfikacji
wielojęzycznej (http://ez.no/community/
Co obiecujemy:
Po przeczytaniu tego artykułu czytelnik
developer/specs/improved_multi_langu- będzie umiał zainstalować eZ publish z
age_in_ez_publish_rev_2). obsługą kilku języków, zmieniać usta-
Ten samouczek przedstawi, jak wienia i konfigurację systemu pod ką-
tem obsługi wielu języków. Tworzyć wła-
tworzyć wielojęzyczne strony webo-
sne rozszerzenia językowe dla eZ pu-
we z użyciem eZ publish, dodawać blish. Dodawać nowe języki do istnieją-
nowe języki do istniejących instalacji cej już instalacji.
i tłumaczyć zawartość strony na róż- Tłumaczyć i tworzyć treść w dostęp-
nych w eZ publish językach.
ne języki.
Co powinieneś wiedzieć:
Wymagania Artykuł jest adresowany do osób, któ-
re mają niewielkie doświadczenie lub
eZ publish pracuje na serwerze webo-
dopiero zaczynają swoją przygodę
wym Apache. Zaleca się używać ostat- z eZ publish, potrzebna jednak będzie
niej wersji z gałęzi 1.3. Upewnij się, że podstawowa wiedza z zakresu tworze-
używasz wersji 4.4 PHP. Zalecamy rów- nia witryn internetowych.
nież używać ostatniej wersji z gałęzi 4.4
jest, by zarówno publiczny siteaccess, jak [FileSettings] fr, de). W eZ publish możemy ograni-
i siteaccess Interfejsu Administracyjnego VarDir=var/news _ site czyć prawa użytkowników tylko do wy-
używały tego samego katalogu (umiesz- branych siteaccess-ów. To oznacza, że
czonego poniżej katalogu var). W przeciw- Katalog 'var' zawiera pliki buforowe (ca- użytkownicy mogą się zalogować tyl-
nym razie niektóre składniki strony (jak pli- che files) i logi. Zawiera również części, ko na strony, na których mają gwaranto-
ki) przerzucone przez interfejs administra- które nie będą przechowywane w bazie wane prawa dostępu przez administrato-
cyjny będą niedostępne publicznie, bo nie (obrazki i pliki) (Listing4). ra. Ponieważ zmieniliśmy istniejącą kon-
będą mieć dostępu do katalogu 'var' site- I konfiguracja jest gotowa. Następny figurację, musimy przekazać eZ publish,
access-u administracyjnego. Należy się krok to ustawienie odpowiednich praw które siteaccess-y są teraz dostępne pu-
też upewnić, że Apache ma wystarczają- dla użytkownika anonimowego do okre- blicznie.
ce prawa do utworzonych katalogów: ślonych publicznych siteaccess-ów (gb, Zaloguj się jako administrator do In-
terfejsu Administracyjnego za pomocą
Listing 8. Łącza tekstowe użytkownika i hasła skonfigurowanego
przez kreator ustawień. Nowy URL do
{def $locales=fetch( 'content', Interfejsu Administracyjnego będzie po-
'translation_list' )}
dobny do www.example.com/site_admin
{foreach $locales as $locale}
<a href={concat( "index.php/"
lub www.example.com/index.php/site_
, $locale.country_code|downcase(), admin, zależnie od nowych ustawień
"/", $DesignKeys:used.url_alias ) konfiguracyjnych i od tego, czy używasz
|ezroot}> metody Virtual Host dla URL-a. Po zalo-
{$locale.country_code }
gowaniu się, przejdź do zakładki Setup
</a>
{delimiter}
i kliknij „Roles and policies”. W liście ról,
| kliknij rolę „Anonymous” i przycisk „Edit”.
{/delimiter} W liście bieżących polityk znajdź nastę-
{/foreach} pujący wiersz:
Module: user, Function: login,
Listing 9. Łącza z obrazkiem flagi
Limitations: SiteAccess()
{def $locales=fetch( 'content', Kliknij ikonę „Edit” (symbol pióra po
'translation_list' )} prawej) i wybierz siteaccess-y „gb”, „de”
{foreach $locales as $locale} i „fr”. Możesz wybrać wiele opcji jedno-
<a href={concat
cześnie, przytrzymując klawisz Control.
( "index.php/",
$locale.country_code| (Rysunek4)
downcase(), "/" Po wybraniu siteaccess-ów, kliknij
, $DesignKeys:used. „OK”. eZ publish zapisze ustawienia poli-
url_alias )|ezroot}> tyki (Rysunek 5).
<img src={concat
Module: user, Function: login, Limita-
( "share/icons/flags/",
$locale.locale_code, ". tions: SiteAccess( gb , fr , de ).
gif" )|ezroot()} alt= Wyjdź z trybu edycji ról klikając
"" border="0" /> „OK”. Zakończyliśmy zatem aktuali-
</a> zację praw eZ publish, a teraz należy
{/foreach}
sprawdzić, czy nasze siteaccess-y są
dostępne publicznie dla użytkowników
Tłumaczenia
Proces konfiguracji jest zakończony.
Teraz możemy zająć się tłumaczeniem
naszej zawartości z użyciem Interfejsu
Administracyjnego eZ publish. Aby prze-
tłumaczyć zawartość na jeden z dostęp-
nych języków.
Zaloguj się do Interfejsu Administra-
Rysunek 8. Definiowanie języków dodatkowych podczas instalacji
cyjnego. Pamiętaj, że nowy URL do In-
terfejsu Administracyjnego będzie po-
dobny do www.example.com/site_admin
lub www.example.com/index.php/site_
admin. (Rysunek 6).
W widoku „Content structure” wy-
bierz obiekt, który chcesz przetłuma-
czyć. Następnie, z listy rozwijanej wy-
bierz „Another language” i kliknij przy-
cisk „Edit”. (Rysunek 7).
W następnym widoku, eZ publish za-
pyta o nowy język do tłumaczenia i o ję-
zyk, z którego będzie tekst tłumaczony.
Wybierz „French” dla tłumaczenia i „En-
glish (United Kingdom)” jako język ba-
zowy i kliknij przycisk „Edit”. Zauważ,
że ten krok zostanie pominięty, jeśli tylko
jeden język dodatkowy zoastał zdefinio-
wany podczas instalacji. (Rysunek 8).
W następnym kroku, eZ publish poka-
że widok edycji dla nowego tłumaczenia.
Na szczycie każdego pola edycji będzie
pokazany tekst w oryginalnym, bazowym
Rysunek 9. Widok edycji dla nowego tłumaczenia języku. Po zakończeniu tłumaczenia klik-
nij „Send for publishing”. (Rysunek 9).
Lista dostępnych tłumaczeń dla bie-
żącego obiektu jest pokazana, gdy ak-
tywna jest zakładka „Translations”. To
również daje dostęp do dodatkowych
opcji. (Rysunek 10).
Jeden Interfejs
Administracyjny, trzy
niezależne strony
wielojęzyczne
Nowa wielojęzyczna funkcjonalność w
eZ publish w wersji 3.8 daje możliwość
tworzenia obiektów niezależnie w wie-
lu językach i używania aliasów URL do
Rysunek 10. Lista dostępnych tłumaczeń dla bieżącego obiektu
dostępu do zawartości w różnych języ- ini.append.php dla publicznego site- Więcej informacji na temat i18n we
kach. Powiedzmy, że chcemy mieć nie- access-u (gb, fr, de), które odetnie na- wzorcach znajdziesz na stronie dokumen-
zależne tłumaczenia, zatem zawartość zwę folderu języka z każdego URL-a. tacji: http://ez.no/doc/ez_publish/technical
dla czytelnika angielskojęzycznego bę- W przeciwnym razie eZ publish bę- _ manua l / 3 _ 8 / r efer enc e / tem p late _
dzie inna, niż zawartość dla czytelnika dzie używał ścieżek np.: http://localhost/ operators /formatting _and_internatio-
francuskojęzycznego. W naszej konfigu- ezpublish/index.php/gb/english, gdzie „gb” nalization/i18n
racji mamy trzy języki, więc powinniśmy jest nazwą siteaccess-u, a „english” na-
stworzyć trzy foldery (po jednym dla zwą katalogu języka pod drzewem głów- Przełącznik języków
każdego języka) w drzewie zawartości. nym eZ publish. Używając ustawienia Pa- Mechanizm przełączania języków zale-
Te foldery będą przechowywały zawar- thPrefix możemy nakazać eZ publish uży- ży od liczby języków skonfigurowanych
tości stron specyficzne dla języka. wanie domyślnie katalogu „English”, ale dla strony. Mając tylko trzy języki, może-
Zaloguj się do Interfejsu Administra- nie używać go w URL-u. W ten sposób my wyświetlać łącza tekstowe, które po-
cyjnego i stwórz trzy foldery w głównym nasza ścieżka będzie wyglądać jak http:// zwalają użytkownikowi na zmianę języ-
drzewie katalogów, po jednym dla każde- localhost/ezpublish/index.php/gb. ka. Jednak jeśli mamy dużo języków, za
go języka: „English”, „French” i „German”. Dodaj następujące ustawienia do dużo miejsca byłoby potrzebne na poka-
(Rysunek 11). publicznych siteaccess-ów (gb, de, fr) zanie wszystkich łączy, zatem zamiast
To wszystko. Teraz mamy zdefinio- w bloku [ SiteAccessSettings]: łączy pokażemy wybór języka poprzez
wane katalogi główne dla zawartości wie- Tak samo, jeśli użytkownik wybierze listę rozwijalną. Przedstawione przykła-
lojezycznej. Zawartość angielska będzie angielski siteaccess, eZ publish będzie dy kodu mogą zostać użyte albo w pa-
przechowywana w folderze „English”, używał folderu „English” jako folder głów- gelayout.tpl (główny wzorzec eZ pu-
francuska w „French” itd. To pozwala na ny angielskiej zawartości. blish), albo we wzorcach węzłów.
segregację zawartości w różnych języ- Oto przykład przełącznika języków,
kach i dostarczania zawartości w okre- Własne tłumaczenia który wyświetla tekst lub łącza obrazkowe
ślonym języku podanym w aliasie URL-a. Podczas tworzenia wielojęzycznych dla każdego języka:
Następnym krokiem jest dodanie usta- stron, czasem potrzebujemy przetłuma- Jeśli używasz ustawień Virtual Host
wień konfiguracyjnych do każdego site. czyć jakieś własne etykiety, które nie są na swojej stronie, usuń „index.php” z
dostępne w domyślnym pliku tłumaczeń URL-a w przykładowym kodzie. Ten
eZ publish. Możemy zaimplementować przykład będzie działał z metodą dostępu
tłumaczenie tych własnych etykiet jako URI. Dla metody dostępu HOST kod bę-
rozszerzenie eZ publish (Rysunek 12). dzie podobny. Załóżmy, że mamy skonfi-
W pliku extension/mytranslationext/ gurowane hosty jak następuje:
settings/site.ini.append.php, potrzebujemy
przekazać eZ publish, że jest dostępne roz- Podsumowanie
szerzenie tłumaczeń. Ten plik domyślnie W tym artykule objaśniliśmy, jak skonfi-
nie jest zakładany – należy go stworzyć. gurować wielojęzyczną stronę za pomo-
eZ publish zapisuje tłumaczenia ja- cą eZ publish, używając cech dostęp-
ko XML w plikach o nazwie translation.ts. nych w wersji 3.8. Przedstawiliśmy prak-
Poniższy zrzut ekranu pokazuje program tyczny przykład, który objaśnił ustawie-
QT Linguist użyty do tłumaczenia zawar- nia konfiguracyjne strony i pokazał jak
tości w pliku XML. To jest plik źródłowy tworzyć nowe tłumaczenia dla obiek-
dla innych tłumaczeń użytych jako roz- tów strony. Strona wynikowa posiada
szerzenie. trzy niezależne językowe siteaccess-
y, wszystkie uruchamiane z jednego In-
Plik translation.ts terfejsu Administracyjnego. Z nowymi
Rysunek 11. Drzewo zawartości
to zwykły plik tekstowy cechami eZ publish 3.8 można dotrzeć
w formacie XML do międzynarodowej publiczności przez
We wzorcach, operator wzorca i18n ozna- dodanie języków do twojej strony. n
cza napis do przetłumaczenia:
Jarek Litwa
Telewizja Internetowa TVNET
tArt w serwisie nazwa.pl. Przejrzysty inter- czyłby sobie tego każdy nieco zagubio-
fejs i wszystkie podstawowe opcje do za- ny klient. Zarówno przestrzeń dyskowa,
rządzania serwerem (podział powierzchni wielkość transferu, jak i możliwość swo-
pomiędzy dowolnymi usługami, zakłada- bodnego podziału przestrzeni są dosko-
nie nowych baz danych, zakładanie kont nałym rozwiązaniem dla firm takich, jak
e-mail) bardzo mi się spodobały ze wzglę- moja gdzie na jednym serwerze prowadzi
du na ogromną prostotę działania. się kilka niezależnych serwisów interneto-
Po wstępnej selekcji rozpoczęliśmy wych, oceniamy na plus.
analizę ofert dwóch firm – NetArt i Ho- Dzisiaj prócz serwisu Telewizji Inter-
me. Obie należą do czołówki dostawców netowej www.TVNET.com.pl na serwe-
usług internetowych i pozostawiły konku- rze są jeszcze dwie nasze domeny. Dlate-
rencję w tyle. Przy porównaniu cen NetArt go szukając firmy, w której postawimy ser-
wypadł lepiej zarówno przy domenach, jak wer dystrybucyjny braliśmy również Net-
i serwerach WWW, dodatkowo zapewnia- Art pod uwagę, ale rozwiązania informa-
Jacek Kmiecik
www.kmiecik.com.pl
Sebastian Zawali
ret.pl
nowych wersji MySQL. Wbrew pozo- to z tego, iż jest to usługa hostingowa,
rom jest to ważne, bo świadczy o tym, a nie serwer wirtualny i stąd te ograni-
że firma rozwija swoją infrastrukturę. czenia.
Spośród wszystkich innych ofert Podsumowując chwale sobie sta-
pod uwagę brałem tylko rozwiąza- bilność serwera – praktycznie, od kie-
nia głównego konkurenta nazwa.pl – dy korzystam z serwerów w nazwa.pl
home.pl, ale niestety ich interfejsy do nie miałem żadnych przerw w wyświe-
obsługi poczty przez WWW nie po- tlaniu stron co zdarzało się u mojego
siadają wersji niemieckiej (posiada poprzedniego dostawcy, aktualizację
tylko polską i angielską). Oprócz te- php'a i MySQL'a, program partnerski,
go jakość samego programu do admi- infolinie 0801, szybkość przypisywania
nistracji serwerem oraz obsługi pocz- domen do serwera, pomoc techniczną
ty przez WWW, jest znacznie wyższa oraz przejrzystość panelu administra-
w nazwa.pl – choć jest to zupełnie su- cyjnego zarówno serwera jak i poczty.
Justyna Zajączkowska
Specjalista ds. Public Relations w NetArt
Maksymilian Drążek
Grupa 505
Prosimy wypełnić czytelnie i przesłać faksem na numer: (22) 887 10 11 lub listownie na adres: Software-Wydawnictwo Sp. z o.o.,
Bokserska 1, 02-682 Warszawa, e-mail: pren@software.com.pl. Przyjmujemy też zamówienia telefoniczne: (22) 887 14 44
Dokładny adres....................................................................................................................................................................................................................
Tytuł
Ilość Od numeru Opłata
Ilość
zamawianych pisma lub w zł
numerów
prenumerat miesiąca z VAT
Software Developer’s Journal (1 płyta CD)
– dawniej Software 2.0 12 250/1801
Miesięcznik profesjonalnych programistów
SDJ Extra (od 1 do 4 płyt CD lub DVD)
– dawniej Software 2.0 Extra! 6 150/1352
Numery tematyczne dla programistów
Suma
Jeżeli chcesz zapłacić kartą kredytową, wejdź na
stronę naszego sklepu internetowego:
1
Cena prenumeraty rocznej dla osób prywatnych
2
Cena prenumeraty rocznej dla osób prenumerujących już Software Developer’s Journal lub Linux+
3
Cena prenumeraty dwuletniej Aurox Linux
www.buyitpress.com
Narzędzia triki w php
Znaki specjalne
Pisząc skrypty w PHP często zdarza dzie PHP. Jest to spowodowane tym iż nie Listing 1. Skrypt PHP bez zastoso-
się, że należy zajrzeć do źródła wyge- ma znaków nowej linii. wania znaków nowej linii
nerowanej strony aby sprawdzić czy W celu uniknięcia takiego problemu
wszystkie elementy zostały wydruko- możemy zastosować znaki nowej linii na <?php
echo 'Ala ma kota';
wane poprawnie. Niestety jeżeli skrypt zakończeniu każdego wiersza.
echo '<br />';
jest w całości napisany za pomocą ję- W tym przypadku źródło strony bę- echo 'Kot ma Ale';
zyka PHP i nie ma w nim miejsc, w któ- dzie podzielone na osobne linie w których ?>
rych zastosowany jest czysty HTML zo- umieściliśmy tekst. Nowe linie powstały w
rientowanie się w źródle programu bę- miejscu gdzie umieściliśmy znak \n. Listing 2. Formatowanie strony z
dzie bardzo ciężkie ze względu na brak Przekształcanie zmiennych wysłanych użyciem znaku nowej linii
nowych linii. Całość strony WWW zosta- za pomocą metody GET i POST w zwykłe <?php
nie wypisana linia za linią bez znaków zmienne echo "Ala ma kota\n";
nowego wiersza. Można tego uniknąć W PHP możesz także przetworzyć echo "<br />\n";
stosując specjalne znaki, które pomo- zmienne z tablicy w zwykłe zmienne. echo "Kot ma Ale\n";
?>
gą w nadaniu dla źródła strony WWW Musisz tylko wybrać, którą tablicę masz
odpowiedniego formatowania. Znakiem zamiar przetwarzać. Jest to zwłasz- Listing 3. Skrypt przetwarzający
specjalnym jest między innymi \n - czyli cza przydatne, kiedy funkcja register_ zmienne z tablicy $_GET
znak oznaczający nową linię. globals jest wyłączona. Funkcję
<?php
Po zajrzeniu do źródła takiej strony zo- register_globals wyłącza się specjal-
if( is_array($_GET) )
baczymy całość tekstu w jednej linii mimo nie w celu uczynienia skryptów bardziej {
iż wypisywaliśmy ja w kilku linijkach w ko- bezpiecznych pod względem użytkowa- while( list($k, $v) =
each($_GET) )
{
if( is_array($_GET[$k]) )
{
while( list($k2, $v2) =
each($_GET[$k]) )
{
$$k[$k2] = $v2;
}
reset($_GET[$k]);
}
else
{
$$k = $v;
}
}
reset($_GET);
}
?>
czasu już tylko wyświetlić zaokrągloną do tości tych zmiennych w formularzach ge-
Listing 15. Specjalna funkcja do za-
odpowiedniej ilości miejsc po przecinku. nerowanych za pomocą PHP będziesz bezpieczania danych przed wprowa-
musiał dane poddać obróbce polece- dzeniem ich do bazy danych
Listing 10. Pobranie czasu począt- niem stripslashes. Jest to spowodowane
kowego faktem iż jeżeli użytkownik wstawi jakiś <?php
$zdanie = "Mark's laptop";
tekst do formularza zostanie on automa-
<?php $zabezpieczone_zdanie =
tyczne oznaczony znakami slash. Więc mysql_real_escape_string($zdanie);
$m_time = explode
(" ",microtime()); przed użyciem polecenia echo, print lub print($zabezpieczone_zdanie);
$m_time = $m_time[0] + podobnego będziesz musiał usunąć sla- ?>
$m_time[1]; she z wartości tych zmiennych.
$starttime = $m_time;
?>
Przekierowanie w PHP
Jeżeli będziesz musiał przekierować użyt- Skrypt ten przekieruje użytkownika czątku pliku. Jeżeli wypiszesz już coś do
kownika do innej strony i będziesz chciał na stronę http://www.google.pl bez poka- przeglądarki wówczas generowanie stro-
zrobić to za pomocą PHP z pomocą przyj- zywania mu jakichkolwiek komunikatów. ny zakończy się błędem.
dzie w tym momencie polecenie header. W celu zmiany adresu URL wystarczy, iż
Pozwala ono na przeniesienie użytkowni- w skrypcie zmienisz tylko adres który jest
Listing 19. Automatyczne przekie-
ka na inną stronę bez jego wiedzy o tym tam obecnie. Funkcja header której uży- rowanie użytkownika
fakcie. Możesz na przykład za pomocą te- łem w tym skrypcie służy do wysyłania
go polecenia zrobić system zliczania ilości nagłówka dokumentu. Jest w niej użyty <?php
header('location:
pobierania pliku. Najpierw tworzysz stronę parametr location co oznacza, iż serwer
http://www.google.pl/');
na której dodajesz jeden do licznika po- ma przejść na odpowiednią stronę WWW.
?>
brań programu, a potem przekierowujesz Funkcja ta zadziała tylko wówczas gdy
użytkownika do pliku który chciał pobrać. zostanie ona wywołana na samym po-
Rozszerzenie plików
Bardzo często podczas przenoszenia pli- będziemy chcieli używać funkcji include()
ków na inny serwer możemy natknąć się należy zaimportować wcześniej przygoto- Listing 20. Plik z rozszerzeniem pli-
na błąd w ich rozszerzeniu. W większości wany kod. Później podczas włączania kodu ków PHP
serwerów jako pliki zawierające skrypty PHP z innych plików wystarczy tylko wyko- <?php
w języku PHP uznawane są pliki posia- rzystać zmienną $RozszerzeniePHP, która $RozszerzeniePHP = 'php';
dające rozszerzenia: .phtml, .php3, .php zawiera rozszerzenie obsługiwane na na- ?>
i .php5. Jeżeli będziemy budować stronę szym serwerze.
Listing 21. Włączanie pliku z roz-
najlepiej jest sobie zapisać rozszerzenie W ten sposób będziemy mogli przeno-
szerzeniem zawartym w zmiennej
plików w osobnym pliku, który będzie je sić nasze skrypty na dowolny serwer, na
przechowywał, gdyż na różnych serwe- którym rozszerzenie plików zawierających <?php
rach są obsługiwane różne rozszerzenia skrypt PHP jest zupełnie inne od zazwy- include('rozszerzenie.inc');
i pomoże to nam uniknąć błędu. Dla prze- czaj stosowanych. Wówczas wystarczy tyl- include('plik. '.$RozszerzeniePHP);
?>
chowywania rozszerzenia stwórz plik roz- ko pozmieniać rozszerzenia plików i war-
szerzenie.inc, w którym zapisz je w dowol- tość zmiennej w pliku rozszerzenie.inc, a
nej zmiennej. Następnie w pliku, w którym cały nasz skrypt będzie działał bez błędów.
Prenumerata PRO
lu konsumenckiego w Europie – Ciao.com. Do
nowo powstałego centrum rozwoju oprogramo-
wania we Wrocławiu poszukujemy doświadczo-
nych programistów PHP. Chcesz dobrze zara-
biać, pracować w międzynarodowym środowi-
sku i w przyjaznej atmosferze – dołącz do nas.
www.ciao-group.com/careers_wroclaw.php
Agencja Interaktywna
– br-design.pl
Kreowanie oraz obsługa serwisów interne-
towych, programowanie aplikacji interneto-
wych według indywidualnych potrzeb klienta,
realizacja projektów graficznych i prezentacji
multimedialnych.
www.br-design.pl
Firma Informatyczna
„Saulewicz”
Wdrażamy technologie internetowe w opar-
ciu o serwery linuxowe i rozwiązania „Open
Source”. Oferujemy aplikacje bazodaniowe
pracujące w środowisku PHP. Prowadzimy
konsultacje dotyczące bezpieczeństwa sys-
Więcej informacji: patrycja.wadolowska@software.com.pl tel.: 022 887-13-45
temów sieciowych.
www.saulewicz.com.pl.
protHOST
Rewelacyjny hosting o12 już od 49 zł netto/rok
(w tym cPanel PL). Rejestracja domen od 1 zł
netto. Webdesign i pozycjonowanie. Wszystko
czego potrzebujesz.
http://o12.pl
Hosting
Elastyczny dobór pakietów, pakiet POCZTA – 40
zł, pakiet START (www, email, 10 domen, php
5, mysql, pgsql) – 150 zł, pakiety KOMFORT,
PROFIT, PROFITSSL, zarządzanie przez cPanel.
Rejestracja domen globalnych, krajowych, funk-
cjonalnych i regionalnych. Ceny od 50 zł.
www: http://www.lubman.pl,
e-mail: biuro@lubman.pl,
Patrycja Wądołowska: Dlaczego zde- dowała o tym jakaś wyszukiwarka, która śmy ten serwis. Pracujemy już nad nowy-
cydował się Pan stworzyć taki serwis? zbiera po drodze wszystkie możliwe lin- mi funkcjami, które zapewnią użytkowni-
Rafał Mrzygłocki: Wszystko zaczę- ki. Po przeanalizowaniu wpadłem na po- kom jeszcze większą wygodę i usprawnią
ło się od mojej prywatnej strony starto- mysł, co pozwoli użytkownikom szyb- korzystanie z sieci.
wej, Zawsze miałem niesamowity bała- ko i łatwo dojść do wartościowych stron. PW: Jakich technologii użyto do stwo-
gan w bookmarkach. Dodawałem bardzo Dlatego oprócz siatki logotypów, powsta- rzenia serwisu? Zakładając, że będzie miał
dużo stron, próbowałem porządkować je ła także wyszukiwarka działająca wśród wielu użytkowników, musi działać bardzo
i grupować w katalogach, ale i tak znale- sprawdzonych i wartościowych stron użyt- wydajnie. Jakie zastosowano rozwiązania?
zienie później jakiejś informacji zajmowało kowników. Według mnie Internet to użyt- RM: U podstaw konstrukcji serwisu le-
mi sporo czasu. Żaden istniejący portal nie kownicy, to oni go tworzą i są najlepszym żały idee elastyczności i skalowalności.
oferował mi satysfakcjonującego rozwiąza- wyznacznikiem, które portale są warto- Poprzez te pojęcia rozumiemy możliwość
nia, dlatego pomyślałem o stworzeniu wła- ściowe i godne polecenia. szybkiej reakcji na zmieniające się potrze-
snej strony. Nie jestem programistą, ko- PW: Jaki jest dzienny przyrost użyt- by naszych użytkowników i klientów, w tym
rzystam jedynie z podstawowych aplikacji, kowników serwisu? często trudny do przewidzenia wzrost ich
dlatego zrobiłem prostą siatkę w HTML-u, RM: Po zaledwie kilku dniach od ofi- liczby. Zdecydowaliśmy się na rozwiązania
na której umieściłem logotypy ulubionych cjalnego startu każdego dnia w iloggo re- open-source nie tylko ze względów ekono-
stron. Z czasem pomysł podchwycili moi jestruje się około 100 nowych użytkowni- micznych, ale w dużej mierze ze względu
znajomi-coraz więcej osób prosiło mnie o ków. To dla nas informacja, że Internau- na możliwość kontroli ich działania. Uwa-
dodawanie kolejnych logotypów i ustawiało tom spodobała się idea serwisu. Najwięk- żamy ponadto, że w tej chwili naszą praw-
sobie siatkę jako stronę startową. szym zaskoczeniem jest dla nas szyb- dziwą siłą jest nie tylko sam publicznie do-
Podsunęło mi to pomysł na stworze- kość, z jaką rośnie katalog iloggo – każda stępny serwis, ale przede wszystkim zbiór
nie ogólnodostępnej siatki, którą każdy minuta to kilkanaście dodanych stron. sprawdzonych narzędzi i procesów, wspo-
użytkownik zdefiniuje, w sposób odpo- Chcemy, żeby iloggo rozwijało się i magających wytwarzanie oprogramowa-
wiadający jego potrzebom. Zainteresowa- zmieniało, dotrzymując kroku użytkowni- nia. Dzięki temu możemy nie koncentro-
ło mnie także to, że niektóre strony miały kom. W każdym miejscu i w każdej chwili wać się wyłącznie na problemach techno-
ogromną ilość użytkowników i odwiedzin, ma spełniać ich wymagania i odpowiadać logicznych, ale skutecznie rozwiązywać
a inne w ogóle. Wiedziałem, że nie decy- na ich potrzeby – po to właśnie stworzyli- nowe biznesowe wyzwania.
Jak sam autor pisze, książka oparta jest na jego doświadczeniach a do rozpoczęcia lektury potrzeba nam jest podstawowa zna-
jomość HTML’a. Programowania w PHP (w książce wykorzystano wersję 5 tego języka i nowe możliwości, jakie ze sobą niesie)
autor uczy nas od podstaw, więc nawet, jeśli PHP to nasz pierwszy język programowania to na pewno damy rade ogarnąć wie-
dzę wiedzę zawartą w podręczniku łącznie z technikami obiektowymi. Podobnie sytuacja ma się z bazami danych autor powie
nam wszystko, co powinniśmy wiedzieć o bazach danych i pokaże przykłady dla MySQL. Unikalną cechą tej książki jest cześć
poświęcona planowaniu aplikacji webowych dzięki temu początkujący deweloperzy nauczą się właściwego toku produkcji opro-
gramowania. Oczywiście przy okazji projektowania dowiemy się, czym jest logiczny podział aplikacji i jak go wykorzystać we wła-
snych projektach. Razem z rozdziałami o testowaniu (testy jednostkowe na przykładzie SimpleTest) i wdrażaniu aplikacji, kontroli
wersji (CVS) poznajemy tajniki tworzenia aplikacji na wysokim poziomie.
Znaczna część książki przeznaczona jest raczej dla początkujących. W związku z powyższym podczas omawiania SSL
dowiemy się o podstawowych zasadach działania internetu a nim przystąpimy do „zabawy” z dokumentami XML przy po-
mocy modelu DOM dowiemy się więcej o języku XML. Bardziej zaawansowanych i tych początkujących po lekturze
pierwszych rozdziałów książki na pewno zainteresuje opis debugowania i obsługi błędów a także dość dobrze opi-
sane aspekty tworzenia witryn międzynarodowych. Autor postanowił również opisać wyrażenia regularne, ale szko-
da, że ograniczył się jedynie do tych zgodnych ze standardem. Niemal każde zagadnienie jest połączone z pro-
stym, ale przydatnym przykładem i tak podczas omawiania Web Serwisów (Web Services) zbudujemy wyszukiwar-
kę używając Google API a zasady działania PEAR poznamy wykorzystując pakiet Date. Omówione zostały także
aspekty bezpieczeństwa dotyczące nie tylko samego kodu PHP, ale również całego środowiska działania aplikacji.
Co więcej autor wraca do tych kwestii przy okazji omawiania innych zagadnień - nie daje to zapomnieć o bezpie-
czeństwie. Całość wiedzy zawartej w książce można przećwiczyć na trzech kompletnych projektach – Blog, system
zarządzania terminami i sklep internetowy. Nie musimy tez martwić się, że książka szybko się rozleci, ponieważ po-
siada ona twarda oprawę a jej strony są zszywane.
Łukasz Witczak
„Almanach PHP” to efekt kolejnej próby napisania podręcznika, w którym zawarte byłyby wszelkie aspekty programowania w
PHP – począwszy od historii języka i instalacji interpretera w różnych środowiskach, poprzez podstawy, po obiektowość PHP 5
oraz problemy związane z wydajnością skryptów i debugowaniem. Czy autorowi udało się zmieścić to wszystko na 382 stro-
nach? Zobaczmy. Lekturę każdej nowej pozycji związanej z technologiami webowymi zaczynam zwykle od sprawdzenia da-
ty jej wydania. W tej branży informacje szybko stają się nieaktualne, zatem szkoda mi czasu na lekturę książek „historycz-
nych”. Pierwsza edycja „Almanachu PHP” została wydana w oryginale (po angielsku) w roku 2005, zatem pierwsze kryte-
rium oceny książki można uznać za zaliczone.
Czas na ocenę treści. Książka napisana jest bardzo przystępnym językiem, którego zrozumienie nie powinno przyspo-
rzyć nikomu żadnych problemów. Wszystkie zagadnienia poparte są sensownymi przykładami. Co ważne, kod w przykła-
dach nie zawiera błędów, co nie jest niestety standardem w podręcznikach z dziedziny informatyki. W książce nie znajdzie-
my przykładów zaawansowanych rozwiązań, ani przepisu na budowę portalu – jest ona raczej przewodnikiem po
języku. Dodajmy, że przewodnikiem dość dokładnym, w którym nie pominięto takich zagadnień jak programowanie
zorientowane obiektowo, transformacje XML, czy obsługa wyjątków (jedna z nowości PHP 5). Zakres zagadnień
jest bardzo szeroki, niestety, ze względu na ograniczoną objętość książki, wiele z nich jest tylko zasygnalizowana i
wymaga dodatkowego przestudiowania w innych źródłach (chociażby w manualu: http://pl2.php.net/manual/pl/).
„Almanach PHP” z całą pewnością mogę polecić początkującym i średnio zaawansowanym miłośnikom języka
PHP. Ci pierwsi będą mogli zacząć swoją przygodę z językiem od nabycia dobrych nawyków programistycznych,
drudzy – zapoznać się ze zmianami i nowymi możliwościami wprowadzonymi w ostatnich wersjach PHP. Ważne,
by Almanach nie był jedyną pozycją w podręcznej biblioteczce. Opisuje on bardzo wiele zagadnień, ale też wiele z
nich jest opisana bardzo pobieżnie i wymaga samodzielnego zgłębienia.
Marcin Stefaniak
Felieton
Własne życie
Aleksander Cynarski
P
ojęcie potęgi informacji w naszych jest to, że tzw. nowoczesne zabawki nie rych możemy pobierać „na żywo” informacje
czasach jest już na tyle banalne są już na tyle drogie, że może sobie na nie – uważam, że może. Wystarczy tylko odro-
i powszechnie używane, że ge- pozwolić tylko mała grupa bogatych szcze- bina samo zaparcia, trochę czasu, no i oczy-
neralnie nie ma sensu o tym wspominać. niaków. Dzięki szybkiemu rozwojowi tech- wiście pomysł. Przecież te wszystkie obraz-
Ale.. no właśnie. Jak rozejrzymy się do- nologii jesteśmy w stanie przenieść do sie- ki, teksty i filmy dostępne on-line za pomocą
okoła najdzie nas myśl – integracja. ci właściwie całe swoje aktualne życie. coraz to bardziej zaawansowanych wyszuki-
Otoczeni komórkami, laptopami, cały Należę do tej grupy ludzi, którzy sie- warek tworzą już wiele nowych przestrzeni,
czas „w sieci” – mnie często aż korci, żeby dzą przed komputerem cały czas – praca, które możemy eksplorować tak samo jak uli-
przenieść tam swoją tożsamość. Wstęp- przyjemność – to jedno i to samo. Chcę jak ce nowo poznanych miast. Idąc dalej w roz-
nie pomysł nieco futurystyczny, ale czy tak największą część swojego realnego życia myślania nad ożywieniem naszego wirtual-
bardzo nie realny? Oczywiście nie mówię przenieść na informacje i publikować, publi- nego ja, możemy zastanowić się nad „per-
tu o wizjach filmowych, ale o czysto „in- kować ile się da. Wracając do przykładu z sonalizacją” nas dla innych. Wiem, że dziw-
formacyjnym przeniesieniu”. Większość z kawiarnią. Wyobraźcie sobie, że wasza ko- nie brzmi, ale już wyjaśniam o co mi cho-
nas posiada blogi, często bawimy się w mórka – a raczej palmofon, który kupiliście dzi. Otóż często spotykamy się z możliwo-
tzw. „social networking” (grono.net czy lin- na jednej z aukcji internetowych ma wbudo- ścią zmiany wyglądu strony, jej rozłożenia.
kedin.com) – piszemy tam o sobie, co ro- wany GPS oraz EDGE lub GPRS. Wysyła- Ale co w przypadku, jeżeli chcemy być dla
bimy, co chcielibyśmy robić. Nasza tożsa- my informację do naszego bloga obsługu- wszystkich „trendi” w realnym życiu nie je-
mość przechodzi ze świata realnego do jącego XMLRPC, w treści której jest nasza steśmy w stanie, ale „tam” możemy. Skoro
wirtualnego bardzo naturalnie. Gramy w aktualna pozycja. Wszystko mamy oczywi- można personalizować pojęcie „jak” to cze-
popularne ostatnio gry MMORPG. Często ście zintegrowane z frappr.com – pokazuje mu nie możemy zrobić tego samego z „co”.
nie zdajemy sobie sprawy, że aby kogoś gdzie jesteśmy. Jeżeli spotkanie jest na ty- Umieśćmy małą sondę przy wejściu na blo-
poznać wystarczy go po prostu poszukać le ciekawe, że nie chcemy aby ktokolwiek ga i już. Niech się pokazują tylko te wpisy
i to w dodatku bez wychodzenia z domu. nam przeszkadzał klikamy „do not disturb” które mogą pasować do proflu osoby oglą-
Współczesne systemy operacyjne, wszech- i już na blogu pokazuje się informacja – „je- dającej. Każdy z nas ogląda filmy science
obecne oprogramowanie publikujące da- stem tu i tu, ale nie radzę przeszkadzać”. fiction – częstym motywem w takowych, któ-
ne on-line, książki adresowe importowane Wszystko to mamy w zasięgu ręki, wystar- re traktują o innych cywilizacjach jest zbioro-
z telefonów i wędrujące gdzieś do baz da- czy ją tylko wyciągnąć. Najlepszą chyba wa świadomość. Umiejętność pewnej gru-
nych. Kalendarze, którymi możemy dzielić rzeczą we współczesnym świecie jest nie- py do swobodnej wymiany informacji. Czy
się ze znajomymi. Ciekaw jestem ilu z Was skończona możliwość tworzenia. Czy aby obecne formy publikowania w sieci, nie są
pozbawionych dostępu do sieci ma wraże- nie warto było by do tego naszego bloga namiastką? Owszem, że do generowania
nie, że czegoś brakuje – ten komputer jest dodać jeszcze informację o kamerach on-li- pełnego obrazu osobowości jeszcze mamy
taki nie pełny. Świat rzeczywisty i ten, w któ- ne znajdujących się najbliżej miejsca w któ- daleko, ale myślę – że to kwestia czasu, no i
rym żywo uczestniczymy w zaciszu własne- rym się znajdujemy, czy też ściągać dyna- oczywiście tego jak się rozwinie technologia,
go biurka są już ze sobą bardzo powiązane. micznie prognozy pogody. Zaś dodając no- w jakim kierunku pójdą producenci sprzętu
Czy można pójść dalej? Czy możemy jesz- we informacje wszystko to automatycznie i dostawcy usług. Ciekawe czy kiedyś du-
cze głębiej zanurzyć się w wirtualne morze trafia do grupy zainteresowanych osób, któ- że firmy ISP wejdą w spółki z firmami pro-
powiązanych informacji? re za pomocą jednego z wielu dostępnych dukującymi hardware i zaczną sprzedawać
Myślę, że tak. Wystarczy odrobina wy- mechanizmów dostają je na swoje małe nie tyle dostęp, co całe zintegrowane plat-
obraźni, łącze do internetu i parę elektro- przenośne zabaweczki w jakiejkolwiek for- formy działające całkowicie on-line. W do-
nicznych zabawek, które zabieramy ze so- mie. Wszystkie te informacje możemy do- mach będziemy mieli gniazda światłowodo-
bą nawet do kawiarni. Po co nasi znajomi, wolnie filtrować, przerabiać i modyfikować we do których będziemy podłączać stacjo-
mają dzwonić i pytać gdzie jesteśmy? Wy- w taki sposób, aby trafiały tam gdzie powin- narne lub przenośne terminale. Zaś całe na-
starczy, że wejdą na naszego bloga i zo- ny. Aktualnie dostępne technologie dyna- sze codzienne i wirtualne życie będzie odby-
baczą gdzie aktualnie spędzamy czas, czy micznej wymiany danych (Publish subscri- wać się jednocześnie. Technologie potrzeb-
mamy ochotę na to by ktoś się przyłączył, be) naprawdę dają wielkie możliwości. ne do wdrażania takich pomysłów już istnie-
czy też nie. Prawie wszystko możemy ak- Dzięki całej masie dynamicznie gene- ją, lecz niestety tak daleka integracja na ra-
tualnie przerobić na bity i wypuścić ich rowanych stron, blogów mogących się in- zie jest tylko fantastyczną wizją, przynajm-
strumień w globalną sieć. A najważniejsze tegrować, portalom tematycznym, z któ- niej jeżeli chodzi o problem skali. n
ites
Recommended s
Klub techniczny
Zend Platform 2
Rozszerzanie serwerowe
Zend Platform 2 jest cebulą w ofercie firmy Zend.
Każdy kto oglądał film Shrek wie o czym mówię
– chodzi o to, że cebula posiada warstwy. Platfor-
mę można zainstalować i zapomnieć o jej istnie-
niu, a i tak będziemy odczuwać pozytywne efek-
ty jej posiadania. Produkt można wykorzystać przy
samodzielnym tworzeniu i dostrajaniu aplikacji
webowych. Cały trik polega na tym, że bez żadne-
go problemu możemy odrzucić warstwy, które są
nam niepotrzebne do pracy i skupić się jedynie na
tych potrzebnych.
Czym więc jest Zend Platform 2? Oto odpo-
wiedź firmy Zend:
„Zend Platform jest solidnym, produkcyjnym
środowiskiem PHP, w którym aplikacje będą za-
wsze działać bez problemu.
Rozwiązanie dedykowane jest dla zastosowań
informatyczno-biznesowych, które wymagają nie-
zawodnych i stabilnych aplikacji osadzonych w śro-
dowisku klasy produkcyjnej. Zend Platform oferuje
wydajność i skalowalność. Rozwiązanie gwarantu-
je bardzo długi czas sprawności aplikacji oraz jej
niezawodność – wszystko to jest możliwe dzię-
ki zastosowaniu mechanizmów monitorowania
PHP oraz narzędzi wspomagających rozwiązywa-
nie problemów. Wymienione właściwości minima-
lizują ryzyko związane z diagnozowaniem błędów Rysunek 1. Rezultaty testów
i pozwalają uniknąć niedogodności związanych
z tym procesem. Reasumując, przy stosowaniu (bądź serwerach). Spróbujmy przekonać się jak stall.sh. Jeśli rzeczywiście tak jest, to należy wspo-
platformy Zend, zarówno Twój czas jak i zasoby fi- to wszystko jest możliwe. mniany plik uruchomić; można to zrobić komendą:
nansowe będziesz mógł w całości wykorzystać
na tworzenie pięknych aplikacji PHP, nie martwiąc ZACZYNAMY ./install
się problemami związanymi z ich uruchamianiem W momencie przygotowywania niniejszego tekstu
i utrzymywaniem.” opisywany produkt jest dostępny w postaci aplika- Skrypt instalacyjny powinien uruchomić graficz-
Ostatnie zdanie w opisie przedstawionym cji nieokienkowej. Do testowania platformy użyłem nego czarodzieja (ang. Wizard). Teraz wystar-
przez Zend na pierwszy rzut oka wydaje się za- dystrybucji Linux Debian. czy wykonywać po kolei instrukcje pojawiające
latywać napuszonym żargonem marketingowym, Na początku należy pobrać pakiet instalacyjny się na ekranie. Nie będę w tym miejscu zawierał
jednakże tak naprawdę w pełni oddaje istotę pro- Zend Platform 2. Pakiet ten, w postaci próbnej jest szczegółowego opisu całego procesu (złożone-
duktu. Mówiąc prosto, Zend Platform 2 to gru- dostępny za darmo na stronie domowej firmy Zend go z około 20 kroków) – opis taki można znaleźć
pa plików, które siedzą między silnikiem PHP (http://www.zend.com). Przed pobraniem paczki w wymienionym wcześniej przewodniku instala-
a skryptami PHP i powodują przyśpieszenie dzia- instalacyjnej trzeba mieć założone konto. cji. Chciałbym za to zwrócić uwagę na dwa istot-
łania skryptów, potrafią śledzić błędy, wykrywają Po ściągnięciu pakietu na serwer czas brać ne szczegóły:
potencjalne problemy i udostępniają śliczny inter- się za instalowanie produktu. Warto w tym miejscu
fejs webowy, który pozwala użytkownikowi moni- nadmienić, że na stronie Zend umieszczony jest • przy wybieraniu typu serwera wybrałem opcję
torować wszystko co dzieje się na jego serwerze bardzo dobry przewodnik instalacji, gdzie można Cluster Manager/Standalone. Użytkownicy ko-
znaleźć bardzo szczegółowe informacje na temat rzystający z pojedynczego serwera, lub insta-
całego procesu. Ten sam przewodnik jest umiesz- lujący pierwszy serwer w klastrze, muszą rów-
Ian Morse mieszka w Kanadzie – na Wyspie
czony w pobranym archiwum tar. Archiwum to na- nież wybrać tę opcję;
Księcia Edwarda; jest właścicielem i kierow-
nikiem firmy konsultingowej specjalizującej leży rozpakować korzystając z komendy gunzip -c • w trakcie instalacji otrzymujemy pytanie
się w technologiach webowych. Witrynę Iana <package name> | tar –xvf o pewne informacje systemowe; na przykład
można obejrzeć pod adresem: Aby rozpocząć instalację należy przejść do o lokalizację pliku php.ini, lokalizację kontrole-
http://www.geckoware.com katalogu utworzonego w trakcie rozpakowywania ra apache, wersję zainstalowanego silnika PHP
pakietu i sprawdzić czy znajduje się tam plik in- itd. Warto otworzyć przed instalacją dodatko-
we okno terminala, dzięki czemu można póź- dla zabawy stworzyć oraz uruchomić skrypt in- Tabela 1. Zend Platform 2
niej łatwo sprawdzić te informacje. tensywnie korzystający z zasobów pamięciowych PHP: 4.3.9 i wyżej, 4.4.x, 5.0.x, 5.1
i zobaczyć co się stanie. Ja użyłem skryptu poka-
Wersja pro-
Po zakończeniu procesu instalacji użytkownik zanego na Listing 1. 2.1.2
duktu
otrzymuje podsumowanie, na którym widać czy Przedstawiony skrypt uruchomiłem dzie-
Linux/Unix, FreeBSD, Solaris,
wszystkie komponenty platformy zainstalowały sięć razy z włączonymi opcjami Code Accelera- O/S:
Mac OS X
się pomyślnie. Na tym kończy się pierwsza war- tion oraz Dynamic Content Caching, a następnie
stwa cebuli Zend Platform. Średnio zaawansowa- powtórzyłem tę czynność – tyle, że wspomnia- Pakiet darmowy w wersji
próbnej. W przypadku zaist-
ny użytkownik może w tym miejscu zakończyć ne opcje były wyłączone. Co ciekawe, w obydwu
nienia chęci stosowania plat-
interakcję z platformą i zacząć pracować ze swo- przypadkach wydajność była podobna. Może to Cennik:
formy w trybie komercyjnym
imi aplikacjami PHP. Użytkownik taki zauważy, że wydawać się zaskakujące, jednak należy zauwa- należy skontaktować się z fir-
wspomniane aplikacje działają teraz o wiele szyb- żyć, że rozważany skrypt nie jest przeznaczony mą Zend.
ciej i stabilniej – i to mu wystarczy. Bardziej za- do testowania obsługi żądań; został on zaprojek-
Adres w sieci: http://www.zend.com/
awansowani użytkownicy mogą uruchomić prze- towany w taki sposób, aby platforma mogła za-
glądarkę internetową i rozpocząć monitorowanie, reagować na potencjalnie niewłaściwy kod – co z moich Serwerów Pobierających (ang. Down-
testowanie i optymalizację swoich rozwiązań, cie- w rzeczywistości nastąpiło! load Server). Na podstawie zamieszonych tam
sząc się pełną gamą możliwości platformy. Jeśli przejdziemy teraz ponownie do zakład- informacji można się przekonać, że wyniki sta-
ki Zend Central to zauważymy, że zanotowano no- ją się coraz bardziej imponujące, proporcjonal-
ROZBIERANIE CEBULI we zdarzenie. Jeśli uruchomimy odpowiednio du- nie do zwiększania się częstotliwości występo-
Aby uzyskać dostęp do webowego interfejsu Zend żo odmiennych skryptów to zaobserwujemy, że wania równoległych żądań do serwera. Przy sto-
Platform 2 należy wpisać w przeglądarce URL okre- niektóre zdarzenia opisują błędy, zaś inne infor- sowaniu Zend Platform ponad połowa z 45 rów-
ślający miejsce instalacji środowiska. Domyślnie mują nas o tym, że kod wykonywany na skrypcie nolegle przychodzących żądań została obsłużo-
jest to: http://<nazwa serwera>/ZendPlatform jest zbyt wolny. Każdy wpis zawiera informacje na w czasie krótszym niż sekunda. Dla mniejszej
Na początku należy się zalogować (domyślna o czasie wykonania, o serwerze na którym docelo- liczby żądań wzrost wydajności wyraźnie spa-
nazwa użytkownika to Admin, hasło zaś definiuje- wy skrypt był uruchomiony oraz o URL, który wy- da, jednak rezultaty są i tak o wiele lepsze niż
my sami w trakcie procesu instalacji). Po pomyśl- wołał zadany skrypt. Informacje te to prawdziwa ko- w przypadku nie korzystania z platformy.
nym zakończeniu tego krok użytkownik jest powi- palnia złota – szczególnie jeśli mamy do czynienia Pozostałe benchmarki oferują testy wydaj-
tany i na wejściu otrzymuje podstawowe informa- z klastrem serwerów. nościowe, testy kompresji oraz testy skryptów.
cje systemowe. Przy pierwszym logowaniu inter- Po kliknięciu na wybrany wpis otrzymujemy We wszystkich tych przypadkach rezultaty są
fejs może wydawać się dość ubogi, jednak polecam nowe okienko typu pop-up, gdzie można znaleźć podobne: korzystając z Zend Platform otrzymu-
jeszcze bardziej szczegółowe informacje na temat jemy mniej więcej dwukrotną poprawę parame-
Listing 1. Skrypt użyty przy pierwszym logowaniu skryptu. Znajdziemy tu miedzy innymi szczegóło- trów będących przedmiotem testowania. Nale-
we zapisy na temat czasu wystąpienia usterki, dłu- ży pamiętać, iż twórcy platformy zaznaczają bar-
// testowanie przyśpieszenia kodu gości jej trwania oraz informacje o zmiennych prze- dzo mocno, że rezultaty testów będą miarodajne
$test_array1 = array(); kazanych do skryptu, a także o dołączonych przez w przypadku występowania odpowiednio wzmo-
$test_array2 = array(); niego plikach. Ukoronowaniem tych wszystkich żonego ruchu na serwerze webowym – takim,
// zapisywanie czasu początkowego testu udogodnień jest fakt, iż Zend Platform 2 integru- który odzwierciedla typowe obciążenie określo-
$start = time(); je się z Zend Studio dzięki czemu możemy z miej- nej witryny.
// sztuczne obciążenie serwera sca naprawiać błędy w kodzie. Dla użytkowników
for($i = 0; $i < 25000; $i++) { nie posiadających tego ostatniego pakietu przewi- PODSUMOWANIE
$test_array[$i] = rand(); dziano możliwość przeglądania kodu bezpośrednio Zend Platform 2 jest dobrze zaprojektowaną
} z przeglądarki. i wysoce wydajną warstwą serwerową, która po-
for($j = 0; $j < 25000; $j++) { Zend Platform 2 oferuje olbrzymią gamę wła- trafi przyśpieszyć i uczynić bardziej niezawod-
$test_array2[$j] = rand(); ściwości, o których można by pisać oddzielne, ną każdą niemalże aplikację PHP. Wydaje się,
} duże artykuły – warto tu wspomnieć chociażby iż każdy system jest w stanie skorzystać z za-
asort($test_array); mechanizm obsługi klastrów serwerowych oraz let wynikających ze stosowania platformy, jed-
asort($test_array2); pomost integracyjny dla platformy Java (ang. nakże najwięcej korzyści czerpać tu będą nie-
$test_array3 = array_merge($test_array, Java Integration Bridge), który (według zapew- wątpliwie witryny pracujące pod bardzo dużym
$test_array2); nień umieszczonych na witrynie Zend) pozwala obciążeniem. Rozwiązanie jest wręcz nieodzow-
asort($test_array3); firmom inwestującym w serwery aplikacji oparte ne dla podmiotów, które nie mogą inwestować
// zapisywanie czasu końcowego testu na platformie J2EE korzystać z zalet PHP. Oczy- w nową infrastrukturę sprzętową i są zmuszone
$end = time(); wiście wszystkie te stwierdzenia muszą mieć do wyciskania wszystkiego co najlepsze z posia-
// obliczanie różnicy czasów pokrycie w konkretnych benchmarkach. Mnie in- danych zasobów. Zend Platform 2 jest również
$difference = $end - $start; teresują konkretne liczby. Jak dobra jest tak na- bardzo przydatne w sytuacji kiedy monitorowa-
// wyświetlenie wyników prawdę platforma Zend? Łatwo to sprawdzić, ja- nie serwera przy pomocy ogólnodostępnych na-
echo "Start: ".$start; ko że benchmark testujący jest wbudowany bez- rzędzi staje się zbyt uciążliwe. Wzrost wydajno-
echo "<br />End: ".$end; pośrednio w system – można go znaleźć pod za- ści, który pociąga za sobą stosowanie platformy
echo "<br />Difference: ".$difference; kładką Performance. Na Rysunku 1 przedstawi- jest ewidentnie znaczący.
łem rezultaty testów wykonanych dla jednego
W sprzedaży od lutego
ROZWIĄZANIA
UWAGA KOLEJNY TEST KONSUMENCKI
n Prototype z PHP
Pokażemy, jak budować nowatorskie systemy
n Relokacje serwerów
rankingowe w oparciu o bibliotekę script.aculo.us
n dla zaawansowanych
NARZĘDZIA
n narzędzia
n eZ publish jako Mulisite CMS
jedna instalacja wiele stron.