Professional Documents
Culture Documents
PRZYKADOWY ROZDZIA
SPIS TRECI
KATALOG KSIEK
KATALOG ONLINE
ZAMW DRUKOWANY KATALOG
TWJ KOSZYK
DODAJ DO KOSZYKA
CENNIK I INFORMACJE
ZAMW INFORMACJE
O NOWOCIACH
ZAMW CENNIK
CZYTELNIA
FRAGMENTY KSIEK ONLINE
Wydawnictwo Helion
ul. Chopina 6
44-100 Gliwice
tel. (32)230-98-63
e-mail: helion@helion.pl
PHP5. Zaawansowane
programowanie
Autorzy: Edward Lecky-Thompson, Heow
Eide-Goodman, Steven D. Nowicki, Alec Cove
Tumaczenie: Adam Byrtek,
Jarosaw Dobrzaski, Pawe Gonera
ISBN: 83-7361-825-2
Tytu oryginau: Professional PHP5
Format: B5, stron: 664
PHP to jzyk umoliwiajcy tworzenie aplikacji sieciowych uruchamianych po stronie
serwera. Jego najnowsza wersja, oznaczona numerem 5, to w peni obiektowy jzyk,
za pomoc ktrego mona budowa nawet najbardziej zoone systemy portalowe,
intranetowe i ekstranetowe. Dziki nowym funkcjom wprowadzonym w PHP 5 moliwe
jest korzystanie z plikw XML i protokou SOAP, wydajna komunikacja z baz danych
i stosowanie technik obiektowych znacznie uatwiajcych i przyspieszajcych tworzenie
rozbudowanych aplikacji.
PHP5. Zaawansowane programowanie to ksika przedstawiajca potne
moliwoci i elastyczno najnowszej wersji tej popularnej platformy programistycznej.
Opisuje podstawowe zasady programowania obiektowego i prowadzenia
rozbudowanych projektw informatycznych. Zawiera informacje o modelowaniu
aplikacji w jzyku UML, stosowaniu wzorcw projektowych i tworzeniu narzdzi,
ktre bdzie mona wykorzysta w kadym projekcie. Przedstawia rwnie analiz
prawdziwego przypadku systemu automatyzujcego prac dziau sprzeday
w przedsibiorstwie handlowym.
Programowanie obiektowe
Jzyk UML i modelowanie systemw
Wzorce projektowe
Tworzenie prostych narzdzi obiektowych
Poczenia z bazami danych
Model MVC
Stosowanie protokou SOAP
Komunikacja z uytkownikiem i mechanizmy sesji
Testowanie aplikacji
Studium przypadku automatyzacja pracy dziau sprzeday
Spis treci
O Autorach ................................................................................................................................................ 13
Wstp ....................................................................................................................................................... 15
Cz I Technologia obiektowa
21
117
Spis treci
249
Spis treci
375
Spis treci
10
Spis treci
11
Dodatki
591
1
Wprowadzenie
do programowania obiektowego
Programowanie obiektowe moe wprowadza zamieszanie w gowach programistw tworzcych gwnie kod proceduralny. Moe, ale nie musi. W niniejszym rozdziale omwimy
podstawowe zagadnienia teoretyczne zwizane z technologi obiektow i poznamy obowizujc w tej dziedzinie terminologi (pen odstraszajcych czasem wielosylabowcw).
Powiemy, dlaczego warto interesowa si technikami obiektowymi i w jaki sposb mog
one znacznie przyspieszy proces programowania rozbudowanych aplikacji oraz uatwi ich
pniejsze modyfikacje.
W dwch nastpnych rozdziaach bdziemy poszerza t wiedz i wgbia si w nieco bardziej
zaawansowane tematy. Ci, ktrzy maj wczeniejsze dowiadczenia z programowaniem obiektowym poza rodowiskiem PHP5, mog te dwa rozdziay pomin. Z drugiej strony, materia
ten moe stanowi dobr powtrk, wic mimo wszystko zachcamy do jego przeczytania.
24
Cz I n Technologia obiektowa
Podejcie obiektowe jest podobne w tym sensie, e obiekty ukrywaj przed sob szczegy
swojej implementacji. Sposb wykonania zadania nie jest istotny dla innych komponentw
systemu. Liczy si to, jakie usugi obiekt moe wykona.
Pojcia klas i obiektw oraz sposoby korzystania z nich przy pisaniu programw to fundamentalne zagadnienia programowania obiektowego. S one w pewnym sensie sprzeczne
z zasadami programowania proceduralnego, czyli programowania korzystajcego z funkcji
i globalnych struktur danych. Jak zobaczymy, podejcie obiektowe ma kilka ogromnych
zalet w porwnaniu z proceduralnym, a nowa implementacja moliwoci programowania
obiektowego w PHP5 przynosi rwnie znaczne korzyci w wydajnoci.
25
Przykad z ycia
Korzyci wynikajce z modularnoci mog wydawa si niewielkie w przypadku prostych
aplikacji, ale podczas wykorzystywania zoonych architektur oprogramowania bywaj potne. Jeden z autorw ksiki pracowa ostatnio nad projektem obejmujcych 200 tysicy
wierszy proceduralnego kodu PHP. Co najmniej 65% czasu powiconego na poprawianie
bdw zmarnowano na wyszukiwanie pewnych funkcji i sprawdzanie, jakie funkcje korzystaj z jakich danych. Pniej stworzono now wersj tego oprogramowania, tym razem
o architekturze obiektowej, ktra okazaa si skada z o wiele mniejszej iloci kodu. Gdyby
aplikacja od pocztku bya pisana w taki sposb, to nie tylko trwaoby to krcej, ale uniknito
by wielu bdw (im mniejsza ilo kodu, tym mniejsza ilo bdw), a proces ich usuwania byby znacznie szybszy.
Jako e podejcie obiektowe zmusza do zastanowienia si nad organizacj kodu, poznawanie struktury istniejcej aplikacji jest o wiele atwiejsze, kiedy doczamy jako nowy do
zespou programistw. Poza tym dysponujemy wwczas szkieletem pomocnym w ustalaniu,
gdzie powinny znale si nowo dodawane cechy funkcjonalne.
Nad wikszymi projektami czsto pracuj wieloosobowe zespoy programistw o rnych
umiejtnociach. Tutaj rwnie podejcie obiektowe ma znaczn przewag nad proceduralnym. Obiekty ukrywaj szczegy implementacyjne przed swoimi uytkownikami. Zamiast
koniecznoci zrozumienia zoonych struktur danych i pokrtnej logiki rzdzcej obszarem
zastosowania aplikacji mniej dowiadczeni czonkowie zespou mog na podstawie skromnej
dokumentacji zacz uywa obiektw stworzonych przez bardziej dowiadczonych programistw. Same obiekty s odpowiedzialne za dokonywanie zmian w danych oraz zmian stanu
systemu.
Kiedy wczeniej wspomniana aplikacja wci jeszcze bya pisana kodem proceduralnym,
nowi programici w zespole czsto musieli powici do dwch miesicy na nauk szczegw zwizanych z aplikacj, zanim stali si produktywni. Po przerobieniu aplikacji na
obiektow nowi czonkowie zespou mogli ju po kilku dniach tworzy obszerne dodatki
do istniejcej bazy kodu. Byli w stanie szybko nauczy si korzysta nawet z najbardziej
skomplikowanych obiektw, poniewa nie musieli w peni rozumie wszystkich szczegw
implementacji reprezentowanych przez nie cech funkcjonalnych.
Teraz, gdy ju wiemy, dlaczego naley rozway zastosowanie paradygmatu obiektowego
jako metody programowania, powinnimy przeczyta kilka nastpnych podrozdziaw, aby
lepiej zrozumie koncepcje lece u podstaw obiektowoci. Potem, ju w trakcie lektury
dwch kolejnych rozdziaw, powinnimy na wasnej skrze odczu zalety tego podejcia.
26
Cz I n Technologia obiektowa
n
Nie naley si przejmowa, jeeli ktry z tych terminw wydaje si trudny do zrozumienia.
Wszystkie zostan wyjanione dalej. Nowo zdobyta wiedza moe cakowicie zmieni nasze
podejcie do realizacji przedsiwzi programistycznych.
Klasy
W otaczajcej nas rzeczywistoci obiekty maj pewn charakterystyk i zachowania. Samochd ma kolor, wag, mark oraz bak paliwowy o pewnej pojemnoci. To jest jego charakterystyka. Samochd moe przyspiesza, zatrzyma si, sygnalizowa skrt lub trbi klaksonem. To s jego zachowania. Te cechy i zachowania s wsplne dla wszystkich samochodw.
Co prawda rne samochody maj rne kolory, ale kady samochd ma jaki kolor. W programowaniu obiektowym klasa umoliwia ustanowienie pojcia samochodu jako czego
posiadajcego wszystkie cechy uznane za wsplne. Klasa to zamknity fragment kodu zoony ze zmiennych i funkcji, ktre opisuj cechy oraz zachowania wsplne dla wszystkich
elementw pewnego zbioru. Klasa o nazwie (samochd) opisywaaby waciwoci i metody wsplne dla wszystkich samochodw.
W terminologii obiektowej charakterystyki klasy okrela si mianem waciwoci. Waciwoci maj nazw i warto. Wartoci niektrych mona zmienia, a innych nie. Na przykad
w klasie wystpiyby zapewne takie waciwoci jak
(kolor) czy
(waga).
Kolor samochodu moe ulec zmianie po lakierowaniu, ale waga samochodu (bez pasaerw
i bagau) jest wartoci sta.
Niektre waciwoci reprezentuj stan obiektu. Stan odnosi si do tych charakterystyk,
ktre ulegaj zmianie w efekcie pewnych zdarze, a niekoniecznie mona je modyfikowa
bezporednio. W aplikacji, ktra symuluje funkcjonowanie samochodu, klasa moe mie
waciwo
(prdko). Prdko nie jest wartoci, ktr mona zmieni tak po
prostu, lecz kocowym efektem iloci paliwa przesanej do silnika, osigw tego silnika oraz
terenu, po jakim porusza si samochd.
Zachowania klas s okrelane mianem metod. Metody klas s skadniowymi odpowiednikami funkcji z tradycyjnych programw proceduralnych. Podobnie jak funkcje, metody mog
pobiera dowoln ilo parametrw, z ktrych kady jest pewnego dopuszczalnego typu.
27
Niektre metody przetwarzaj zewntrzne dane, przesane jako parametry, ale mog rwnie
dziaa na waciwociach wasnych obiektw, odczytujc ich wartoci na potrzeby wykonywanych dziaa (na przykad metoda
, ktra symuluje nacinicie pedau gazu,
moe sprawdza ilo pozostaego paliwa, by ustali, czy przyspieszenie jest moliwe) albo
zmieniajc stan obiektw poprzez modyfikacj takich wartoci jak prdko samochodu.
Obiekty
Na pocztek klas mona potraktowa jako wzorzec, na postawie ktrego konstruowany jest
obiekt. Podobnie jak na podstawie tego samego projektu (wzorca) mona zbudowa wiele
domw, tak samo moliwe jest stworzenie wielu egzemplarzy obiektw jednej klasy. Jednak
projekt domu nie precyzuje takich szczegw jak kolor cian czy rodzaj posadzki, ustalajc
jedynie, e takie rzeczy istniej. Klasy funkcjonuj podobnie, okrelajc zachowania i charakterystyki obiektu, nie przesdzajc o ich konkretnej wartoci lub stanie. Obiekt to element
konkretny skonstruowany na podstawie wzorca dostarczonego przez klas. Oglne pojcie
dom mona porwna do klasy. Z kolei nasz dom (okrelony reprezentant pojcia dom)
mona porwna do obiektu.
Majc projekt czy wzorzec i jakie materiay budowlane, moemy zbudowa dom. W programowaniu obiektowym, aby zbudowa obiekt, posugujemy si klas. Proces ten nazywa
si tworzeniem egzemplarza i wymaga dwch rzeczy:
n
Sama klasa nie moe mie przypisanych wartoci do waciwoci albo by w jakim stanie.
Mog to jedynie obiekty. Aby zbudowa dom, trzeba posuy si projektem. Dopiero potem
moemy pomyle o tapetowaniu i panelach zewntrznych. Podobnie konieczne jest stworzenie egzemplarza obiektu klasy, zanim bdziemy mogli operowa na jego waciwociach
lub wywoywa jego metody. Klasami manipulujemy w czasie pisania programu, modyfikujc kod metod i waciwoci. Obiektami manipulujemy w trakcie wykonywania programu,
przypisujc wartoci waciwociom i wywoujc metody. Pocztkujcy adepci programowania obiektowego czsto nie s pewni, kiedy powinni posugiwa si pojciem klasy, a kiedy
obiektu.
Po utworzeniu obiektu mona go przystosowa tak, by implementowa wymogi obszaru
zastosowania aplikacji. Przyjrzyjmy si dokadnie, jak to si robi w PHP.
Tworzenie klasy
Zacznijmy od prostego przykadu. Zapisz poniszy kod w pliku o nazwie class.Demo.php:
28
Cz I n Technologia obiektowa
I ju. Wanie stworzylimy klas . Co prawda nie wyglda imponujco, ale to nic innego
jak podstawowa skadnia deklarowania nowej klasy w PHP. Uywamy sowa kluczowego
, aby poinformowa PHP, e mamy zamiar zdefiniowa now klas. Po nim podajemy
nazw klasy, a tre klasy zawieramy pomidzy klamr otwierajc a zamykajc.
Wane jest zdefiniowanie jasnej konwencji organizowania plikw z kodem rdowym.
Dobr zasad jest umieszczanie kadej klasy w osobnym pliku i nadanie mu nazwy
class.[NazwaKlasy].php.
Aby utworzy obiekt, najpierw naley si upewni, czy PHP wie, gdzie odnale deklaracj
klasy poprzez doczenie pliku z treci klasy (w tym przykadzie jest to class.Demo.php),
potem wywoa operator i poda nazw klasy oraz par nawiasw. Warto zwracana
przez t instrukcj zostaje przypisana do nowej zmiennej . Teraz mona ju wywoywa metody obiektu i odczytywa lub ustawia jego waciwoci o ile zosta
w takowe wyposaony.
Mimo e klasa, ktr wanie stworzylimy, w zasadzie nic nie robi, wci stanowi poprawn
definicj klasy.
Dodawanie metody
Klasa nie bdzie zbyt przydatna, jeeli nie bdzie nic robi. Przyjrzyjmy si wic, jak
stworzy metod. Pamitajmy, e metoda klasy to po prostu funkcja. Piszc tre funkcji pomidzy klamrami otwierajcymi i zamykajcymi definicj klasy, dodajemy do klasy now
metod. Oto przykad:
!"
#$
"%&'()*+%
Obiekt stworzony na postawie klasy moe teraz wywietli pozdrowienia dla kadego, kto
wywoa metod
Obiekt jest teraz w stanie wywietli tekst przyjaznego pozdrowienia. Operator suy do
dostpu do wszystkich metod i waciwoci obiektw.
29
Dodawanie waciwoci
Dodawanie waciwoci do klasy jest rwnie proste jak dodawanie metody. Wystarczy
zadeklarowa zmienn w obrbie klasy, ktra bdzie przechowywa warto waciwoci.
W kodzie proceduralnym, jeeli chcielimy przechowa jak warto, to przypisywalimy
j zmiennej. W programowaniu obiektowym do przechowywania wartoci waciwoci rwnie uywamy zmiennej. Zmienna ta jest deklarowana na pocztku deklaracji klasy, w obrbie klamer, ktre zamykaj w sobie kod klasy. Nazwa zmiennej jest nazw waciwoci.
Jeeli zmienna nazywa si
, to tworzymy waciwo zwan
.
Otwrzmy plik class.Demo.php i zastpmy jego tre nastpujcym kodem:
!"
#$
"%&'()*" ,+%
Deklaracja nowej zmiennej to wszystko, czego trzeba, by stworzy waciwo klasy
zwan . Dostp do tej waciwoci wymaga posuenia si tym samym operatorem
() co w poprzednim przykadzie oraz nazw waciwoci. Nowa wersja metody
ukazuje, jak realizujemy dostp do tej waciwoci.
Stwrzmy nowy plik o nazwie testdemo.php i wpiszmy w nim nastpujcy kod:
,-"!
.
"
.
"
,/01
, #$
.
"
, #$
30
Cz I n Technologia obiektowa
chcemy mie moliwo ustawiania i pobierania wartoci waciwoci . Jak wida, sposb dziaania metody
Poza zmiennymi przechowujcymi wartoci waciwoci klasy mona deklarowa inne zmienne przeznaczone do wewntrznego uytku w klasie. Obydwa rodzaje danych s wsplnie
nazywane wewntrznymi zmiennymi skadowymi klasy. Cz z nich jest dostpna spoza
klasy jako waciwoci, a inne nie s dostpne i su tylko wewntrznym potrzebom klas.
Jeeli, na przykad, klasa musiaaby pobra z jakiego powodu informacj z bazy danych, mogaby zachowywa uchwyt do poczenia z baz danych w wewntrznej zmiennej
skadowej. Sam uchwyt do poczenia z baz danych trudno nazwa waciwoci samochodu jest jedynie czym, co umoliwia klasie wykonanie pewnych operacji.
31
32
Cz I n Technologia obiektowa
sprawdzania prawidowoci danych dla pewnej waciwoci, naley mimo to zaimplementowa j, posugujc si funkcjami
i , aby moliwe byo dodanie takiego sprawdzania,
albo zmian logiki obszaru zastosowania w przyszoci.
Zawsze uywajmy metod dostpowych dla waciwoci. Uatwi to implementacj przyszych
zmian w wymaganiach logiki obszaru zastosowania aplikacji i kontroli prawidowoci
zmiennych.
Inicjalizacja obiektw
Dla wielu stworzonych klas potrzebna bdzie specjalna procedura inicjalizacyjna wykonywana w chwili tworzenia egzemplarza obiektu tej klasy. Konieczne moe by, na przykad,
pobranie jakich danych z bazy lub zainicjalizowanie jakich waciwoci. Tworzc specjaln
metod, zwan konstruktorem, zaimplementowan w PHP funkcj ,, *+, moemy
wykona wszelkie czynnoci konieczne dla zainicjalizowania obiektu. PHP automatycznie
wywoa t funkcj w chwili tworzenia egzemplarza obiektu.
Moemy, na przykad, napisa nastpujc, now wersj klasy :
2"
!"
""
" ,
!"
#$
"%&'()*" ,+%
Funkcja ,, zostanie automatycznie wywoana w chwili tworzenia nowego egzemplarza klasy .
Uwaga dla uytkownikw PHP4: w PHP4 konstruktory obiektw byy funkcjami o nazwach
takich samych jak nazwa klasy. W PHP5 zdecydowano si na zastosowanie jednorodnej
formy konstruktora. Dla zachowania kompatybilnoci wstecz PHP najpierw szuka funkcji
o nazwie ,, , po czym, jeeli takiej nie znajdzie, szuka jeszcze funkcji o nazwie takiej samej jak nazwa klasy (w poprzednim przykadzie byaby to
$
*+).
Jeeli mamy klas, ktra nie wymaga adnej szczeglnej procedury inicjalizacyjnej, aby mc
normalnie dziaa, nie trzeba tworzy konstruktora. Jak widzielimy w pierwszej wersji klasy
, PHP automatycznie robi wszystko, co potrzeba, by utworzy sam obiekt. Konstruktory
naley pisa tylko wtedy, gdy s potrzebne.
33
Likwidowanie obiektw
Zmienne obiektw, ktre tworzymy, s usuwane z pamici systemowej w chwili zakoczenia wykonywania kodu biecej strony, kiedy zmienna zniknie z biecego zakresu lub kiedy
jawnie zostanie jej przypisana warto pusta. W PHP5 mona uchwyci moment likwidacji
obiektu, by wykona w tym czasie pewne czynnoci. W tym celu naley stworzy funkcj
zwan ,, nie pobierajc parametrw. Funkcja ta, o ile istnieje, jest wywoywana,
zanim obiekt zostanie zlikwidowany.
Poniszy przykad zapisuje w chwili likwidacji obiektu informacj w pliku dziennika zdarze
o tym, jak dugo obiekt istnia. Jeeli mamy obiekty, ktre szczeglnie obciaj pami lub
procesor, to taka technika moe przyda si w analizie wydajnoci systemu i przy szukaniu
sposobw redukcji nadmiernego obcienia.
Tak jak w wikszoci podanych w tej ksice przykadw korzystajcych z baz danych
platform jest tu PostgreSQL. Zdaniem autorw zaawansowane funkcje, obsuga transakcji
i sprawny mechanizm procedur skadowanych tej bazy czyni z niej lepsz alternatyw dla
MySQL-a i innych relacyjnych baz danych typu open-source przeznaczonych do tworzenia
duych, profesjonalnych baz danych. Czytelnicy, ktrzy nie dysponuj rodowiskiem PostgeSQL, mog dokona odpowiednich modyfikacji dostosowujcych do uywanej platformy
bazodanowej.
Stwrzmy tabel, zwan !
, posugujc si nastpujc instrukcj SQL:
&:/.;/;.<=/%"#1%
%"#1%-/:>.=?:>@.:AB/A4C;4D==*
%' %2EFF4C;4D==*
%
%"7"
34
Cz I n Technologia obiektowa
"
/7"
4
I
JK'#) L''K0#
%-/=/&;M%' M%*M%
M%N:C@"#1H$/:/"#1 03">
%
3#" ,
<*
!+
"
/7"
%<JK0'# #1
# "1 #
%
!+3
"
/7"
-'13
"#1J '+
0"3!"#
" ,0 03">
" ,0"O' P
" ,0 "
0"O
P
!"
3"4
"" ,
!"
3"
"
"" ,0 "
!"
"4
" ,
" ,0 D0"3"
!"
"
"
0 "
" ,0 "
0 "
" ,0 D0"3"
!"
0 ""
!+" ,0 D0"3
"
D?
.;/%"#1%-/;
%M%' M%%3 "3" ,%*%
%M%
M%%3 "3" ,0 "
%%
%H$/:/"#1%" ,0
3#" ,
<*
!+
"
/7"
H# "KJJK0
0' 1"''#0#
//Koniec operacji na bazie danych. Zamknicie poczenia.
3
" ,
<
35
Konstruktor tego obiektu nawizuje poczenie z baz danych , posugujc si kontem
domylnego superuytkownika
. Uchwyt do tego poczenia zostaje zachowany
jako prywatna zmienna skadowa do pniejszego uycia. Warto
- przesana jako
parametr do konstruktora suy do skonstruowania instrukcji SQL, ktra pobiera informacje
o artykule przechowywanym w bazie pod podan wartoci klucza gwnego. Dane z bazy
s wwczas przypisywane do prywatnych zmiennych skadowych, z ktrych mona korzysta za pomoc funkcji
i . Zwrmy uwag, e w razie jakiegokolwiek niepowodzenia konstruktor generuje wyjtek, naley wic pamita o zawieraniu wszelkich prb konstruowania obiektw (
w blokach .
Dwie metody dostpowe,
&*+ i
*+, umoliwiaj pobieranie wartoci
prywatnych zmiennych skadowych. Podobnie &*+ i *+ umoliwiaj
przypisywanie im nowych wartoci. Zauwamy, e w chwili przypisywania nowej wartoci
zmienna .
jest ustawiana na . Jeeli nie nastpiy adne zmiany, nic nie
musi by aktualizowane.
Dla testu stworzymy plik o nazwie testWidget.php i wpiszemy do niego nastpujc tre:
H03"
"#
H03" H03"Q
"%4' "#1JR%
H03",3"4%M%
"%C "#1JR%
H03",3"
"
%M%
H03", "4;1
H03", "
"
;1
0I#'3+
"/7"
0%H# "KJ
R%,3"@ 3
Zobaczmy, jak ogromne moliwoci ma ta technika. Pobieramy obiekt z bazy danych, zmieniamy waciwo tego obiektu i automagicznie zapisujemy zmienione dane w bazie za
pomoc kilku zaledwie wierszy kodu w testWidget.php. Jeeli nic si nie zmienia, powrt do
bazy danych nie jest potrzebny i dziki temu zmniejszamy obcienie serwera bazy danych
i zwikszamy wydajno aplikacji.
36
Cz I n Technologia obiektowa
Korzystajcy z obiektu niekoniecznie musz zna wewntrzny sposb jego dziaania. Jeeli
bardziej dowiadczony programista w zespole napisze klas (
, moe przekaza j nowicjuszowi, ktry, na przykad, nie zna SQL-a, a ten moe uy tego obiektu bez wiedzy, skd
pobierane s dane i w jaki sposb dokonuje si w nich zmian. Mona nawet zmieni rdo
pochodzenia danych z PostgeSQL na MySQL albo nawet na plik XML bez wiedzy modego programisty, ktry nie musi ani o tym wiedzie, ani modyfikowa jakiegokolwiek kodu,
w ktrym wykorzystuje t klas.
Ta doskonaa technika zostanie zaprezentowana szerzej w rozdziale 7., w ktrym natrafimy
na uoglnion wersj powyszej klasy, zwan / " , ktrej moemy bez adnych
modyfikacji uywa w praktycznie kadym projekcie.
Dziedziczenie
Gdyby zdarzyo si nam tworzy aplikacj obsugujc stan magazynowy w komisie samochodowym, prawdopodobnie potrzebne byyby nam klasy typu , ! i 01, ktre
odpowiadayby takim wanie typom pojazdw bdcych na stanie komisu. Nasza aplikacja
musiaaby nie tylko pokazywa ilo tego rodzaju pojazdw na stanie, ale rwnie charakterystyk kadego z nich, aby handlowcy mogli informowa klientw.
Sedan to samochd czterodrzwiowy i najprawdopodobniej zapisa trzeba by liczb miejsc
oraz pojemno baganika. Pikap nie posiada baganika, ale ma pak o okrelonej pojemnoci, a cay samochd ma pewn dopuszczaln adowno (maksymalna waga adunku, jaki
moe bezpiecznie przewozi). W przypadku samochodu typu minivan przyda si liczba drzwi
przesuwnych (jedne lub dwoje) oraz liczba miejsc w rodku.
Jednak wszystkie te pojazdy s tak naprawd tylko pewnymi typami samochodw i jako takie
bd miay wiele wsplnych cech w naszej aplikacji, takich jak kolor, producent, model, rok
produkcji, numer identyfikacyjny samochodu itp. Aby wszystkie klasy miay te wsplne waciwoci, mona by po prostu skopiowa kod, ktry je tworzy, do kadego z plikw z definicjami klas. Jak wspomniano wczeniej w tym rozdziale, jedn z zalet podejcia obiektowego jest moliwo wielokrotnego wykorzystania kodu, nie musimy wic kopiowa kodu, bo
moemy ponownie skorzysta z waciwoci i metod tych klas w ramach procesu zwanego
dziedziczeniem. Dziedziczenie to zdolno jednej klasy do przejmowania metod i waciwoci klasy nadrzdnej.
Mechanizm dziedziczenia pozwala na zdefiniowanie klasy bazowej, w tym przypadku 2
, i okrelenie, e inne klasy s typu 2
i std maj takie same waciwoci
i metody co wszystkie obiekty klasy 2
. Moemy ustali, e jest klas typu
2
i dlatego automatycznie dziedziczy wszystko, co zostao zdefiniowane w klasie
2
bez koniecznoci kopiowania kodu. Potem wystarczy napisa jedynie te waciwoci i metody klasy , ktre nie s wsplne dla wszystkich obiektw klasy 2
.
Pozostao wic jedynie zdefiniowa rnice podobiestwa midzy klasami zostan odziedziczone po klasie bazowej.
Moliwo wielokrotnego wykorzystania kodu to jedna zaleta dziedziczenia, ale jest te druga, bardzo wana. Powiedzmy, e mamy klas z metod 2
. Metoda
ta pobiera tylko jeden parametr, obiekt klasy 2
, a w wyniku jej dziaania wydrukowane zostan wszystkie papiery dokumentujce transakcj sprzeday, a samochd zosta-
37
nie usunity z listy pojazdw na stanie. Poniewa wszystkie obiekty typu , ! czy
01 to obiekty typu 2
, mona przesa kady z nich do funkcji oczekujcej
obiektu 2
. Z uwagi na to, e trzy szczeglne typy s potomkami bardziej oglnej
klasy nadrzdnej, wiemy, e bd miay ten sam podstawowy zbir waciwoci i metod.
Dopki potrzebne s tylko metody i waciwoci wsplne dla wszystkich obiektw 2
, moemy zaakceptowa obiekty kadej klasy, ktra jest potomkiem 2
.
Przeanalizujmy przykad kotw. Wszystkie koty maj pewne wsplne zachowania. Jedz,
pi, mrucz i poluj. Maj te wsplne waciwoci wag, dugo wsw i szybko
biegania. Z kolei lwy maj grzywy pewnej wielkoci (a przynajmniej samce) i rycz. Gepardy
maj ctki. Udomowione koty nie maj adnej z tych rzeczy, tym niemniej wszystkie wymienione zwierzta to koty.
W PHP definiujemy klas jako podzbir innej klasy, uywajc sowa kluczowego 3 ,
ktre mwi PHP, e deklarowana wanie klasa powinna odziedziczy wszystkie waciwoci i metody po swej klasie bazowej oraz e chcemy doda nowe cechy funkcjonalne lub
wyspecjalizowa now klas.
Gdyby naszym zadaniem byo napisanie aplikacji udostpniajcej dane o zwierztach w zoo,
prawdopodobnie potrzebowalibymy klas (kot), 4 (lew) i (gepard). Zanim
przejdziemy do pisania kodu, warto zaplanowa hierarchi klas za pomoc diagramw UML,
aby mie jaki punkt wyjcia przy pisaniu kodu i tworzeniu dokumentacji klas (diagramom
UML przyjrzymy si dokadniej w rozdziale 2., wic nie obawiajmy si, jeeli nie do koca
rozumiemy to, co tutaj pokazano). Nasz diagram klas powinien ukazywa klas bazow
oraz podklasy i 4 bdce jej potomkami (patrz rysunek 1.1).
Rysunek 1.1.
Klasy 4 i dziedzicz wszystko po klasie , ale klasa 4 dodaje implementacj
waciwoci 4
(dugo grzywy) oraz metod *+ (ryczenie), a klasa
dodaje waciwo " (ilo ctek).
Implementacja klasy powinna wyglda nastpujco:
&"
3"//w kg
!&
38
Cz I n Technologia obiektowa
1=3"
7-0//w km/h
!"
"
//kod realizujcy jedzenie
!"
//kod realizujcy spanie
!"
"?#
?#
//kod realizujcy polowanie na obiekty typu Prey (ofiara),
//ktrych nie bdziemy definiowa
!"
"%%%M%
Ta prosta klasa definiuje wszystkie waciwoci i metody wsplne wszystkim kotom. Aby
stworzy klasy 4 (lew) i (gepard), mona by skopiowa cay kod z klasy
do tych klas. Stwarzamy jednak wtedy dwa problemy. Po pierwsze, jeeli znajdziemy bd
w klasie , bdziemy musieli pamita o tym, aby poprawi go rwnie w klasach 4
i . I tak oto do zrobienia mamy wicej, a nie mniej (a w kocu zmniejszenie nakadu
pracy jest pono jedn z podstawowych zalet metody obiektowej).
Po drugie, wyobramy sobie, e istnieje metoda jakiego innego obiektu, ktra wyglda
nastpujco:
!"
";B""#&"
&"
&",
Co prawda gaskanie () lwa lub geparda moe nie by rozsdnym pomysem, ale jeeli
uda si nam podej na tyle blisko, eby to zrobi, zapewne zaczn mrucze (). Przesanie obiektu klasy 4 i do metody 56*+ powinno by moliwe.
Potrzeba wic innego sposobu na stworzenie klas 4 i , a sposobem tym jest wanie
dziedziczenie. Posugujc si sowem kluczowym 3 i okrelajc nazw klasy rozszerzanej, moemy w prosty sposb stworzy dwie nowe klasy, ktre maj te same waciwoci
co klasa , uzupeniajc je o swoje wasne. Na przykad:
&"
=
7"0 &"
=3"//w cm
!"
"%:
+%
39
Moemy wic wywoywa waciwoci i metody klasy bazowej bez koniecznoci przepisywania jej kodu. Pamitajmy, e sowo kluczowe 3 nakazuje PHP automatyczne
doczenie wszystkich cech funkcjonalnych klasy do metod i waciwoci specyficznych
dla klasy 4. Poza tym informuje PHP, e obiekty klasy 4 s rwnie obiektami klasy
i e moliwe jest wywoywanie funkcji 56*+ z obiektem klasy 4, nawet
jeeli w deklaracji funkcji uyto nazwy jako wskazwki dla parametru:
0 =
=
=
?"" &"
?"",";B""#
=
W ten sposb wszelkie zmiany dokonane w klasie zostaj automatycznie uwzgldnione
w klasie 4. Poprawki, zmiany wewntrznego sposobu dziaania funkcji albo nowe metody
i waciwoci s przesyane dalej do podklas klasy nadrzdnej. W duej, dobrze zaprojektowanej hierarchii obiektw moe to znacznie uatwi poprawianie bdw i dodawanie ulepsze. Drobna zmiana w jednej klasie nadrzdnej, moe mie ogromny wpyw na dziaanie
caej aplikacji.
W kolejnym przykadzie zobaczymy, jak mona rozszerza i specjalizowa klas za pomoc
specjalnego konstruktora.
Utwrzmy nowy plik o nazwie class.Cheetah.php i wprowadmy do niego nastpujcy kod:
&"
&"7"0 &"
C!-
"
!"
""
" ,7-0Q66
40
Cz I n Technologia obiektowa
Poniszy kod wpiszmy w pliku testcats.php:
&"
!"
";B""#&"
&"
!
&",7-0F
&",
"%40 L
3J 1)1
"1,
00 L'L01
(K%
&",7-0%1
"T 3
0'L+%
&" &"
";B""#
&"
&" &"
";B""#
&"
Klasa dodaje now publiczn zmienn skadow " (ilo ctek) oraz
konstruktor, ktry nie wystpowa w nadrzdnej klasie . Teraz, kiedy stworzymy nowy
obiekt , waciwo 3 (odziedziczona po klasie ) zostanie zainicjalizowana
wartoci 100 kilometrw na godzin, co jest w przyblieniu maksymaln prdkoci osigan przez gepardy na krtkich dystansach. Zauwamy, e niepodanie wartoci domylnej dla
klasy sprawia, e warto zmiennej 3 dla funkcji 56*+ wynosi 0 (a dokadnie warto pusta, czyli
Zastpowanie metod
To, e klasa jest potomkiem innej klasy, nie oznacza, i zawsze musi korzysta z implementacji funkcji pochodzcej od przodka. Gdybymy pisali aplikacj, ktra oblicza pola rnych
figur geometrycznych, mogyby pojawi si w niej klasy 7
(prostokt) i 5
(trjkt). Obydwie figury s wieloktami i jako takie bd potomkami klasy
(wielokt).
Klasa
bdzie miaa waciwo " (ilo bokw) oraz metod
2
(zwr pole). Obliczenie pola jest moliwe dla kadego wielokta, ale metoda jego obliczania
bdzie dla kadego wielokta inna (istnieje oglne rwnanie pola wielokta, ale czsto okazuje si mniej wydajne ni rwnania dla konktretnych figur w tym przypadku prostych
wieloktw). Wzr na pole prostokta to $8$, gdzie jest szerokoci prostokta, a jego
wysokoci. Pole trjkta to 9:;$8$$8$, gdzie to jego podstawa, a to wysoko. Rysunek 1.2 przedstawia niektre przykady obliczania pl rnych wieloktw.
41
Rysunek 1.2.
42
Cz I n Technologia obiektowa
Zdolno jednej klasy do dziedziczenia metod i waciwoci innej klasy jest jedn z najbardziej pocigajcych cech systemw obiektowych, pozwalajc na uzyskanie niesamowicie
wysokiego poziomu efektywnoci i elastycznoci aplikacji.
W naszym przykadzie stworzymy dwie klasy 7
(prostokt) i < (kwadrat).
Kwadrat to szczeglny przypadek prostokta. Wszystko, co mona zrobi z prostoktem,
mona rwnie zrobi z kwadratem, ale z uwagi na to, e w prostokcie wystpuj dwie dugoci bokw, a w kwadracie tylko jedna, niektre operacje trzeba wykona inaczej.
Stwrzmy plik class.Rectangle.php i dodajmy do niego nastpujcy kod:
:"3
3"
0"
!"
"" 0"*3"
" , 0" 0"
" ,3"3"
!"
3".
"" ,3"U" , 0"
W kodzie tym zastpiony zosta zarwno konstruktor, jak i metoda
2*+. Aby kwadrat
mg by kwadratem, wszystkie boki musz by tej samej dugoci. W efekcie konstruktor
potrzebuje tylko jednego parametru. Jeeli do funkcji przesanych zostanie wicej parametrw, to wszystkie oprcz pierwszego zostan zignorowane.
43
PHP nie generuje bdu, jeeli liczba parametrw przekazanych do funkcji zdefiniowanej
przez uytkownika jest wiksza ni liczba ustalona w treci deklaracji. W wielu przypadkach takie zachowanie jest podane. Wicej na ten temat mona wyczyta z dokumentacji wbudowanej funkcji ,
,
*+.
44
Cz I n Technologia obiektowa
//Tutaj akurat wartoci wpisano na stae,
//ale normalnie powinny pochodzi z bazy danych
0"#
0"O "
4PQ666666
0"OPV@
''1
//Przypisuje wartoci z bazy danych do obiektu
" ,0 "
>
" ,0"OP
" , "
40"O "
4P
45
Interfejsy
Czasami mamy grupy klas powizane relacjami niekoniecznie polegajcymi na dziedziczeniu. Zdarza si, e zupenie odmienne klasy maj pewne wsplne zachowania. Na przykad
zarwno soik, jak i drzwi mona otworzy i zamkn, mimo e poza tym faktem nie maj
ze sob nic wsplnego. Niezalenie od rodzaju soika i drzwi obydwu tym rzeczom mona
przypisa te same operacje, ale poza tym nic ich nie czy.
Co robi interfejsy?
Taka sama idea jest obecna w programowaniu obiektowym. Interfejs pozwala na okrelenie,
e obiekt jest w stanie wykona pewn funkcj bez koniecznoci tumaczenia, w jaki sposb
si to odbywa. Interfejs to swoista umowa pomidzy niepowizanymi obiektami zawizana
w celu wykonania wsplnej funkcji. Obiekt, ktry implementuje dany interfejs, gwarantuje
uytkownikom, e potrafi wykona wszystkie funkcje wymienione w specyfikacji interfejsu.
Rowery i piki to zupenie rne rzeczy, a mimo to obiekty reprezentujce te rzeczy w oprogramowaniu sklepu sportowego musz prowadzi interakcj z tym systemem.
Deklarujc interfejs, po czym implementujc go w obiektach, moemy umoliwi zupenie
rnym klasom dostp do wsplnych funkcji. Przedstawiony tu przykad opiera si na raczej
prozaicznej analogii do drzwi i soika.
Stwrzmy plik o nazwie interface.Opener.php:
"!C
""!"
46
Cz I n Technologia obiektowa
""!"
47
!"
1
" ,
10!
nastpnie class.Jar.php:
"!C
V" C
2"
""
!"
""
""
" ,
""
""
!"
"% J
1'
"J
" "#%
!"
"% J
1'
"J'1L"#%
Aby skorzysta z tych plikw, stworzymy w tym samym katalogu jeszcze jeden plik o nazwie
testOpenable.php:
V
!"
-
"3C
,
V V%3"1%
-
"3
-
"3
V
48
Cz I n Technologia obiektowa
Stosujc interfejsy w aplikacji, moemy urzeczywistni komunikacj pomidzy dwoma zupenie niepowizanymi z sob obiektami z gwarancj, e ich interakcja bdzie odbywa si
w ramach warunkw okrelonych w interfejsie. Interfejs jest umow udostpniajc pewne
metody.
Hermetyzacja
Jak wspomniano wczeniej w tym rozdziale, obiekty pozwalaj na ukrycie szczegw ich
implementacji przed ich uytkownikami. Nie musimy wiedzie, czy wspomniana wczeniej
klasa 1
(wolontariusz), zachowuje informacje w bazie danych, w zwykym pliku
tekstowym czy w dokumencie XML lub innym mechanizmie przechowywania danych, aby
mc wywoa metod
.*+. Podobnie nie musimy wiedzie, czy dane wolontariusza
przechowywane w obiekcie s reprezentowane jako pojedyncze zmienne, tablica czy moe
inny obiekt. Zdolno do ukrywania implementacji to hermetyzacja. Oglnie rzecz biorc,
hermetyzacja ma dwa aspekty ochrona wewntrznych danych klasy przed zewntrznym
kodem oraz ukrywanie szczegw implementacji.
Sowo encapsulate oznaczajce hermetyzowanie w jzyku angielskim oznacza dosownie
umieszczenie w kapsule lub w innym wyodrbnionym pojemniku. Dobrze zaprojektowana
klasa, buduje szczeln barier wok swego wntrza i udostpnia dla zewntrznego kodu
interfejs, ktry jest cakowicie odseparowany od tego wntrza. Ma to dwie zalety: moemy
w kadej chwili zmienia szczegy implementacji, nie wywierajc wypywu na dziaanie
kodu korzystajcego z klasy, a take mamy pewno, e nic spoza klasy nie moe niepostrzeenie zmodyfikowa wartoci okrelajcych stan i waciwoci obiektu zbudowanego z klasy
i tym samym ufa, e stan obiektu i wartoci waciwoci bd prawidowe.
Zmienne i funkcje skadowe klasy maj okrelon widzialno. Widzialno odnosi si do
tego, co jest widoczne dla kodu spoza klasy. Prywatne funkcje i zmienne skadowe nie s
dostpne dla kodu zewntrznego i su potrzebom wewntrznej implementacji klasy. Skadowe chronione s widoczne tylko z poziomu podklas danej klasy. Skadowe publiczne
mog by wykorzystywane z poziomu kadego kodu, z wntrza i spoza klasy.
Oglnie rzecz biorc, wszystkie wewntrzne skadowe klasy powinny by deklarowane jako
prywatne. Kady dostp do tych zmiennych dla kodu spoza klasy powinien by realizowany poprzez metody dostpowe. Nikt z nas nie zgodziby si zapewne na degustacj nowej
potrawy z zawizanymi oczami i przez karmienie na si. Wolelibymy przyjrze si daniu
i zadecydowa, czy naprawd chcemy je zje. Podobnie, kiedy obiekt chce dopuci moliwo zmiany swoich waciwoci lub innego rodzaju wpywu na wewntrzne dane z poziomu
zewntrznego kodu, to dziki hermetyzacji dostpu do tych danych za porednictwem funkcji
publicznych (i zachowaniu prywatnoci wewntrznych danych) zyskujemy moliwo weryfikacji zmian i ich akceptacji bd odrzucenia.
Jeeli, na przykad, tworzymy aplikacj dla banku, ktra obsuguje szczegy zwizane z rachunkami klientw, to by moe bdziemy mieli obiekt 2 (rachunek) z waciwoci
?
(saldo kocowe) oraz metod !*+ realizujc wpat i metod !
(
*+ realizujc wypat. Waciwo reprezentujca bilans powinna by tylko
do odczytu. Jedynym sposobem na zmian salda jest dokonanie wpaty lub wypaty. Gdyby
zaimplementowa waciwo
?
jako skadow publiczn, to moliwe byoby
napisanie kodu, ktry zwikszaby warto tej zmiennej bez koniecznoci dokonywania wpaty.
49
Takie podejcie nie byoby zbyt dobre dla banku. Lepiej wic zaimplementowa t waciwo jako prywatn zmienn skadow i udostpni publiczn metod zwan
5
?
*+, ktra zwraca warto prywatnej zmiennej skadowej. Poniewa zmienna przechowujca warto salda rachunku jest prywatna, nie mona bezporedni ni manipulowa.
Z uwagi na to, e jedynymi publicznymi metodami, ktre maj wpyw na saldo rachunku,
s !(
*+ i !*+, zwikszenie salda rachunku bdzie wymagao dokonania wpaty.
Umoliwiajc ukrycie szczegw implementacji i ochron dostpu do wewntrznych zmiennych skadowych, programowanie obiektowe pozwala na tworzenie stabilnych i elastycznych
aplikacji.
Hermetyzacja danych wewntrznych i implementacji metod umoliwia systemowi oprogramowania obiektowego ochron i kontrol dostpu do danych oraz ukrywanie szczegw
implementacji.
Zmiany w PHP5
dotyczce programowania obiektowego
Obiekty byy obsugiwane w PHP ju od wersji PHP3. Nie wizao si to jednak z intencj
obsugi idei klas i obiektw dodano jedynie pewn ograniczon obsug, bardziej w formie
dodatku dostarczajcego skadniow osod (posugujc si sowami Zeeva Suraskiego)
tablicom asocjacyjnym. Obsuga obiektw w PHP pierwotnie stanowia wygodny sposb
grupowania danych i funkcji, ale uwzgldniaa tylko niewielki podzbir cech funkcjonalnych,
jakie posiaday jzyki w peni obiektowe. W miar wzrostu popularnoci PHP stosowanie
podejcia obiektowego stawao si coraz powszechniejsze w duych aplikacjach. Saba implementacja obiektowoci zacza krpowa ruchy.
Co najwaniejsze, nie byo adnej obsugi prawdziwej hermetyzacji. Nie mona byo opisywa zmiennych czy metod jako prywatnych lub chronionych. Wszystko byo publiczne, co,
jak widzielimy, bywa rdem problemw.
Nie byo te obsugi abstrakcyjnych interfejsw i metod. Metody i zmienne skadowe nie
mogy by deklarowane jako statyczne. Nie istniay destruktory. Wszystkie te pojcia byy
znane kademu, kto mia do czynienia z innym jzykiem obiektowym i brak tych moliwoci w modelu obiektowym PHP utrudnia przejcie do PHP z takich jzykw jak Java (ktra
obsuguje wszystkie te aspekty). Ci, ktrzy mieli wczeniej dowiadczenia z PHP4, mog
z poniszej tabeli wyczyta nowe cechy modelu obiektowego wprowadzone w PHP5.
Nowa cecha
Korzyci
Prywatne i chronione
Od tej chwili rwnie PHP umoliwia pen hermetyzacje i ochron danych.
zmienne i funkcje skadowe.
Ulepszona obsuga
usuwania porednioci.
50
Cz I n Technologia obiektowa
Nowa cecha
Korzyci
Zmienne i metody
skadowe mog by
statyczne.
Jednorodna posta
konstruktorw.
Obsuga destruktorw.
Obsuga abstrakcyjnych
klas i interfejsw.
Sugestie typw
parametrw.
Mona wskaza klas dla tych parametrw funkcji, ktre oczekuj obiektu.
Piszc !"
!
<
<, mamy pewno, e typ parametru
jest zgodny z naszymi oczekiwaniami
Podsumowanie
W rozdziale omwilimy koncepcj programowania obiektowego. Opisalimy klas jako
wzorzec dla tworzenia obiektw. Obiekty to istniejce w czasie egzekucji zbiory funkcji i danych stworzone na podstawie definicji klas. Obiekty maj cechy charakterystyczne zwane
waciwociami i zachowania zwane metodami. Waciwoci mona postrzega jako zmienne,
a metody jako funkcje.
Niektre klasy maj wsplnego przodka. Kwadraty s prostoktami. Kiedy deklarujemy klas
jako podtyp klasy nadrzdnej, dziedziczy ona metody i waciwoci klasy nadrzdnej. Moliwe jest zastpowanie metod odziedziczonych. Mona napisa zupenie now implementacj lub zdecydowa si na uycie implementacji pochodzcej od przodka i dodanie do niej
kodu specjalizujcego charakterystycznego dla danej podklasy. Mona te w ogle nie zastpowa metody.
Hermetyzacja to wane pojcie w programowaniu obiektowym. Oznacza ono zdolno klasy
do ochrony dostpu do swoich wewntrznych zmiennych skadowych i odgrodzenia uytkownikw klasy od szczegw implementacyjnych. Metody i waciwoci maj trzy poziomy
widzialnoci prywatny, chroniony i publiczny. Skadowe prywatne mog by uywane
wycznie przez wewntrzne operacje klasy. Skadowe chronione s widoczne z poziomu
podklas. Skadowe publiczne mog by uywane przez kod spoza klasy.
Obsuga programowania obiektowego w PHP ulega powanej modernizacji w PHP5 i module Zend Engine 2. Nowe cechy i znaczne zwikszenie wydajnoci czyni PHP jzykiem
obiektowym w penym tego sowa znaczeniu.