background image

indeks

co na cd

newsy

z okładki

fi rma

magazyn

programy

warsztat



97

INTERNET.luty.2004

PHP





C

zego nowego możemy się spodziewać w PHP5? Przede wszyst-
kim obiektów! Nowy model obiektowy zadziwia możliwościami. 
Wprowadzono też obsługę wyjątków (błędów), wzorowaną na 

takich językach jak Java czy C++. Druga wersja silnika Zend oraz nowy 
menedżer pamięci powodują, że PHP5 działa szybciej, lepiej i stabilniej.

Niektóre rozwiązania zaprezentowane w artykule można zastosować 

w PHP4, ale zostały one przytoczone w celu lepszego zrozumienia różnic, 
jakie występują między wersjami 4 i 5. Ponadto niektóre opcje w ofi cjalnym 
wydaniu PHP5 mogą wyglądać i działać trochę inaczej niż w wersji beta.

Nowy model obiektowy

Sposób obsługi obiektów w PHP5 został całkowicie przebudowany, 
co zaowocowało zwiększeniem wydajności. W poprzednich wersjach 
PHP obiekty traktowane były jak zwykłe typy zmiennych (np. zmienne 
całkowite czy ciągi znaków). Każde odwołanie się do takiego obiektu 
(przypisanie  go  do  zmiennej  czy  przekazanie  go  jako  parametru  jakiejś 
funkcji) skutkowało stworzeniem jego kopii. W nowym wydaniu modelu 
obiektowego do każdego obiektu tworzony jest tzw. uchwyt (ang. handle), 
czyli identyfi kator, przy użyciu którego odwołujemy się do niego. Sposób 
tworzenia obiektów i ich obsługi jest jednakowy w PHP4 i 5.

$obiekt = new MojaKlasa(); 

//inicjacja obiektu 

klasy MojaKlasa

$obiekt->wyswietl _ imie();  

//wywołanie metody 

klasy MojaKlasa

$zmienna = $obiekt->Imie; 

//przypisanie do 

zmiennej właściwości klasy MojaKlasa

Wielu programistów do dzisiaj nie wie o takim sposobie obsługi obiektów 

w PHP4, dlatego też zmiana ta nie powinna w jakikolwiek sposób wpłynąć 
na działanie aplikacji napisanych w PHP4. W najgorszym wypadku trzeba 
będzie wprowadzić do istniejących już programów drobne poprawki. Aby 
ułatwić przejście z PHP4 
do PHP5, twórcy zaimple-
mentowali w PHP5 opcję 
auto-clone, która spowo-
duje wymuszenie kopio-
wania obiektów w taki 
sposób, jak to było ob-
sługiwane we wcześniej-
szych wersjach PHP.

Konstruktory i destruktory

W PHP4 sposób obsługi konstruktorów był bardzo prosty: ta metoda klasy, 
która nazywała się tak samo jak klasa, traktowana była jako konstruktor. 
Natomiast destruktorów nie było w ogóle. W PHP5 sytuacja ta zmienia się 
diametralnie. Wprowadzono zunifi kowaną obsługę konstruktorów oraz 
destruktorów poprzez stworzenie metod __construct oraz __destruct. 
Konstruktor wywoływany jest przy każdym stworzeniu nowego obiek-
tu, natomiast destruktor chwilę przed jego zniszczeniem. Uruchomienie 
skryptu z listingu 1 (patrz CD) spowoduje wyświetlenie komunikatów 
pokazanych na rys. 2a.

Publiczne, prywatne, zastrzeżone

Na wzór takich języków jak C++, Pascal czy Java w PHP5 rozgraniczono 
także dostęp do właściwości oraz metod klasy. Istnieją trzy słowa kluczo-
we, które umożliwiają określenie dostępu do danej metody czy właściwości 
klasy: public, private oraz protected. Ramka obok przedstawia różnice wy-
stępujące między nimi, a listing 2 (na CD) – ich praktyczne zastosowanie.

Mimo że najnowsza wersja PHP, oznaczona numerem 5, nie jest 

jeszcze dostępna, już dziś możemy poznać jej możliwości dzięki 

pojawiającym się coraz częściej wersjom beta (najświeższa 

to beta 3, do pobrania z serwisu http://www.php.net). Wszystko 

wskazuje na to, że „piątka” odniesie wielki sukces.

Sebastian Marek

Rys. 1. PHP 5 w wersji beta 2

Dostęp do właściwości i metod klasy

Public 

   Private 

   Protected

Właściwość lub metoda klasy 

Tylko metody należące do tej 

Tylko metody należące do tej 

jest dostępna spoza niej. 

 

samej klasy mają dostęp do 

samej klasy lub do klasy

Oznacza to, że można się do 

właściwości lub metod tej 

 

dziedziczącej mają dostęp

niej odwołać bezpośrednio.   

klasy. 

 

 

 

do właściwości lub metod

 

 

 

 

 

 

 

 

tej klasy.

Rys. 2. Tak jak w innych językach programowania, tak i w PHP5 

konstruktor i destruktor są automatycznie wywoływane w momencie 

stworzenia oraz zniszczenia obiektu (a), a dostęp do pól 

i metod obiektu można ograniczyć (b)

Wszyst

kie listingi

 z tego a

rty-

kułu zn

ajdują s

ię na do

łączo-

nej płyc

ie CD w k

atalogu

 

PHP5-p

rzyklad

owe list

ingi.

Co nowego

Co nowego

w piątej wersji PHP

w piątej wersji PHP 

 

background image

indeks

co na cd

newsy

z okładki

fi rma

magazyn

programy

warsztat



98

INTERNET.luty.2004

PHP





Wyjątki

W PHP4 programowało się łatwo, szybko i przyjemnie do momentu, gdy 
w kodzie wystąpił jakiś błąd. Tragedia następowała wtedy, gdy według 
nas aplikacja chodziła stabilnie, a od klienta dostawaliśmy informację, że 
coś nie działa. Widzę programistów błagających o pomoc: dlaczego nie ma 
obsługi wyjątków? No i są! Na wzór innych języków programowania dosta-
jemy w prezencie pętlę try…catch oraz wspomagającą obsługę wyjątków 
klasę macierzystą Exception.

Na przykładzie z listingu 3 (patrz CD) przeanalizujemy zastosowanie 

wyjątków. Stworzyłem prostą klasę MojaKlasa zawierającą dwie metody: 
GetYear() i SetYear(), oraz jedną właściwość $Year. Naszym zadaniem jest 
sprawdzenie poprawności parametru metody SetYear() – parametr ten po-
winien przyjmować wartości od 2003 do 2005. 

if ( $ _ year > 2003 && $ _ year <= 2005 )

{

  $this->Year = $ _ year; 

}

Jeżeli będzie inaczej, poinformujemy o tym użytkownika stosownym 

komunikatem. Gdy parametr tej metody przyjmie wartość mniejszą od 
2003, spowodujemy stworzenie wyjątku, przypisując mu poniższy komu-
nikat oraz numer błędu:

elseif ( $ _ year < 2003 )

{

   

throw new Exception( ”Rok nie może być mniejszy od 

2003”, 1 );

}

Podobnie zabezpieczymy się w przypadku, gdy parametr metody przyj-

mie wartość większą od 2005:

elseif( $ _ year > 2005 )

{

   

throw new Exception( ”Rok nie może być większy od 

2005”, 2 );

}

Na koniec zabezpieczymy się przed wystąpieniem nieprzewidywalnego 

błędu:

else

{

   

throw new Exception( ”Rok musi zawierać się między 

2003 a 2005”, 0 );

}

Metody SetYear() oraz GetYear() umieszczamy w bloku kodu try. W 

tym miejscu PHP5 czeka na wystąpienie błędu (a dokładnie na utworze-
nie nowego obiektu klasy Exception). Jeżeli cała operacja przebiegnie 
bezbłędnie, nic się nie stanie (tzn. wykonane zostaną powyższe metody 
i wyświetlona zawartość pola Year), w przeciwnym wypadku wykonane 
zostaną instrukcje zawarte w bloku kodu catch. W naszym przypadku wy-
świetlimy szczegółowe informacje na temat powstałego błędu:

catch ( Exception $e )

{

   

echo ”Błąd nr ” . $e->getCode() . ” – ” . $e-> 

getMessage();

   

echo ” (” . $e->getFile() . ” – linia ” . $e-> 

getLine() . ” ) ”;

}

Zapytacie: skąd mamy wziąć informacje na temat tego błędu? Tu przy-

chodzi z pomocą wspomniana klasa Exception. Można oczywiście napisać 

własną klasę obsługującą wyjątki, ale po co wyważać otwarte drzwi. 
W zasadzie zaleca się do obsługi wyjątków używanie klasy Excep-
tion, a w przypadku chęci jej rozbudowy, stworzenie na jej podstawie 
klasy potomnej. Nam jednak w zupełności ona wystarczy. W ramce 
obok znajdują się dostępne pola oraz metody klasy Exception. Listing 
3 obrazujący całość zagadnienia jest dostępny na CD.

Rys. 3. Wystąpienie wyjątku w aplikacji

Elementy wspomagające obsługę obiektów

Dodatkowo w PHP5 znalazło się kilka elementów pomocnych w ob-
słudze obiektów. Można na przykład określić, że argumentem jakiejś 
metody ma być obiekt danej klasy (tzw. type hinting):

<?php

class MojaKlasa

{

  //kod klasy MojaKlasa

}

Specyfikacja klasy Exception

Konstruktor
_ construct(string  $message=NULL,

 

Tworzy nowy obiekt klasy

int code=0)

 

 

 

Exception generując domyślnie

 

 

 

 

komunikat „Unknown exception”

 

 

 

 

oraz  kod  błędu  równy  0

 

 

 

 

(w naszym przykładzie

    samodzielnie 

określamy 

przy

    tworzeniu 

obiektu 

komunikat

 

 

 

 

oraz kod błędu).

Pola klasy
protected $message = ’Unknown

  

Pole przechowujące komunikat

exception’

 

 

 

błędu (domyślnie przyjmuje

 

 

 

 

wartość „Unknown exception”).

protected $code = 0

 

 

Pole przechowujące kod błędu

    (domyślnie 

przyjmuje 

wartość 

0).

protected $fi le

 

 

 

Pole przechowujące ścieżkę

    dostępu 

oraz 

nazwę 

pliku,

 

 

 

 

w  którym wystąpił błąd.

protected $line

   

 

Pole przechowujące nr linii

 

 

 

 

w pliku, w którym wystąpił błąd.

Metody klasy
getMessage()

 

 

 

Metoda zwracająca zawartość

    pola 

$message;

getCode()

 

 

 

Metoda zwracająca zawartość

    pola 

$code;

getFile()

 

 

 

Metoda zwracająca zawartość

 

 

 

 

pola $fi le;

getLine()

 

 

 

Metoda zwracająca zawartość

 

 

 

 

pola $line;

background image

indeks

co na cd

newsy

z okładki

fi rma

magazyn

programy

warsztat



99

INTERNET.luty.2004

PHP





class InnaKlasa

{

   

public function Konwertuj( 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

MojaKlasa $obiekt )

  {

    //kod metody Konwertuj

  }

}

$obiekt1 = new InnaKlasa();

$obiekt2 = new MojaKlasa();

$obiekt1->Konwertuj( $obiekt2 );

?>

Ze względu na to, że dostęp do obiektu jest 

realizowany poprzez uchwyt, straciliśmy „na-
turalną” metodę pozyskiwania kopii danego 
obiektu. Dodatkowo, PHP4 nie umożliwiał 
w żaden sposób użycia konstruktora kopiujące-
go. W PHP5 dostępna jest teraz metoda __clo-
ne(), która nie tylko umożliwia stworzenie du-
plikatu danego obiektu, ale dodatkowo pozwala 
na zdefi niowanie  wartości  poszczególnych  pól 
tej klasy w skopiowanym obiekcie. Jeżeli taka 
metoda została zdefi niowana w defi nicji klasy, 
jest ona wywoływana w momencie skopiowania obiektu. Jeżeli natomiast 
programista nie zdefi niował takiej metody, wywoływana jest domyślna 
jej postać, która ma za zadanie skopiować do nowego obiektu zawartość 
wszystkich pól. Całość ilustruje listing 4 – patrz CD.

Wprowadzono również możliwość defi niowania  stałych  wewnątrz 

klasy:

class MojaKlasa

{

  const Stala = ”Stała wartość”;

}

echo ”Wartość stałej <i>Stala</i> klasy <i>Moja 

Klasa</i>: <b>” . MojaKlasa::Stala . ”</b>”;

oraz obsługę próby dostępu bądź przypisania wartości do nieistniejącego 
pola klasy. W tym celu należy tylko zdefi niować  następujące  metody: 
__get() oraz __set(). Jeśli odwołamy się do pola, które nie istnieje, zosta-
nie automatycznie wywołana metoda __get(), a gdy spróbujemy przypisać 
jakąś wartość nieistniejącemu polu klasy, wywołana zostanie metoda 
__set(). Do obsługi nieistniejących metod klasy wykorzystać można 
metodę __call():

<?php

echo ”<center><h1>Obsługa nieistniejących pól 

i metod w PHP5 – metody <i> _ _ set(), _ _ get()</i> 

oraz <i> _ _ call()</i></h1></center>”;

class MojaKlasa

{

  public $x;

  

  function _ _ get( $name )

  {

    echo ”Nastąpiła próba wywołania nieistniejącego 

pola <b>$name!</b><br/>”;

  }

 

function _ _ set( $name, $value )

  {

     

echo ”Nastąpiła próba przypisania do 

nieistniejącego pola <b>$name</b> wartości 

<b>$value</b>!<br/>”;

  }

  

  function _ _ call( $name, $value )

  {

     

echo ”Nastąpiła próba wywołania nieistniejącej 

metody <b>$name</b> z argumentami: <br/>”;

    var _ dump( $value );

  } 

}

$obiekt = new MojaKlasa();

$obiekt->y = 15;

echo ”Oto pole: ” . $obiekt->z . ”<br/>”;

echo ”Oto metoda: ” . $obiekt->Ustaw( ”Styczeń”, 5, 

TRUE ) . ”<br/>”;

?>

Artykuł ten opisuje właściwości PHP5 w wersji beta. Przypuszczalnie 

więc w ofi cjalnej wersji twórcy PHP na pewno czymś nas jeszcze zaskoczą 
– czymś pozytywnym oczywiście. Ale nawet biorąc pod uwagę tylko te 
zmiany, które tu opisałem, można stwierdzić, że „piątka” będzie na piątkę.



Rys. 4. Wykorzystanie konstruktora kopiującego (a) 

oraz stałych wewnątrz klasy (b)

Rys. 5. Implementacja metod __get(), __set() oraz __call()