: Home / PHP / artykuły / Pseudo-przestrzenie nazw a'la PEAR
Pseudo-przestrzenie nazw a'la PEAR
Ocena użytkowników: / 0
SłabyŚwietny 
Wpisany przez Patryk yarpo Jar   
poniedziałek, 26 lipca 2010 19:55

PHP posiada w najnowszych wersjach (od 5.3.3) wbudowany mechanizm przestrzeni nazw. Wcześniej takiego mechanizmu nie było - lub można uznać, że była jedna wspólna przestrzeń nazw. Jednak wykorzystując zalety OO [ang. Object Oriented] PHP5  można uzyskać bardzo podobny efekt do rzeczywistych przestrzeni nazw. Jest to konwencja zaczerpnięta z repozytorium PEAR.

 

Na początek

  • choćby podstawowa wiedza nt. OO PHP5
  • umiejętność ładowania skryptów za pomocą autoloadera
  • serwer www (może być lokalny np. WAMP)
  • jakieś 10-15 minut

 

Prosta idea

W językach, które opierają się na przestrzeniach nazw (pakietach, modułach - zwał, jak zwał), np. Java pakiety są pogrupowane w katalogi. I tak, kiedy mamy taką strukturę katalogów:

1./java
2.    /util
3.        /Data.java
4.    /sql
5.        /Connector.java
6. 
7. 
8.    

W takiej sytucji do klasy Data mielibyśmy taką ścieżkę:

1.java.util.Data zmienna = new java.util.Data();

Oczywiście można użyć tam mechanizmu importów, pozwalających na wykluczenie java.util. Chciałem jednak pokazać, jaka jest zasada w językach "dojrzalszych" obiektowo niż PHP5.

 

PHP5 i konflikty nazw

W PHP5 możemy uzyskać bardzo podobny efekt. Załóżmy, że mamy taką strukturę katalogów ("pakietów"):

1./Validation
2.    /Type.php
3.    /Value.php
4.    /Exception
5.         /Type.php
6.         /Value.php
7. 
8.    

Jeśli chcemy zatem załączyć odpowiednie pliki stosujemy:

1.require_once 'Validation/Exception/Type.php';
2.require_once 'Validation/Type.php';
3.$oValidator = new Type(); // tworze obiekt walidujacy typy zmiennych
4. 
5.    

Niestety w PHP sama struktura katalogów nie tworzy przestrzeni nazw. Tak więc klasy z plików `Validation/Type.php' i `Validation/Exception/Type.php' nazywają się `Type'. Co powoduje konflikt nazw. Dodatkowo przy załączaniu plików mamy wiele dodatkowych nic-nie-robiących linii kodu. A można temu zapobiec, przy odpowiedniej konwencji.

 

Konwecja PEAR

Skoro mamy już odpowiednią strukturę katalogów, to może użyć metody znanej np. z Javy czy C#: Poniższy kod nie będzie działał, ale ma pokazać do czego dążymy:

1.$oValidator = new Validation.Type();

Jak już powiedziałem, to jest kod, który nie działa w PHP. Po prostu PHP nie posiada operatora kropki, który miałby tu wykonać upragnioną przez nas funkcjonalność. Dlaczego jednak nie wprowadzić znaku podkreślenia, zamiaast kropki? Wtedy kod wyglądałby tak:

1.$oValidator = new Validation_Type();

W takiej sytuacji należy jeszcze zmienić definicję klasy:

1.class Type { ... }

na

1.class Validation_Type { ... }

Przy załączaniu robimy identycznie jak poprzednio:

1.require_once 'Validation/Exception/Type.php';
2.require_once 'Validation/Type.php';
3.$oValidator = new Validation_Type(); // tworze obiekt walidujacy typy zmiennych
4. 
5.    

I już po konflikcie nazw. Klasa w pliku `Validation/Exception/Type.php' nazywa się `Validation_Exception_Type', a z pliku `Validation/Type.php' - `Validation_Type'. Co prawda trochę nam się wydłużył kod, jednak uzyskaliśmy bardzo porządaną cechę kodu - modularność. Co nam po wcześniejszej "modularności" jeśli mieliśmy klasę `User' w "module" forum i klasę `User' w module "Newsletter". Wtedy obie miały taką samą nazwę, teraz `Forum_User' oraz 'Newsletter_User'... Oczywiście, to rozwiązanie nadal nie jest idealne - nadal konflikt może się zdarzyć. Jest jednak mniej prawdopodobny.

 

Automatyczne załączanie klas

Skoro w nazwie skryptu, definiujemy jego położenie, to dlaczego nie wykorzystać odpowiednio autoloadera?

01.function __autoload($name)
02.{
03.    $dirs = explode('_', $name);
04.    $path = implode('/', $dirs) . '.php';
05.    // echo $path . '<hr />'; odkomentuj ta linie, jesli chcesz zobaczyc co sie laduje
06.    if (file_exists($path))
07.    {
08.        require_once $path;
09.    }
10.    else
11.    {
12.        die('blad'); // przed zabiciem skryptu, mozesz wyslac sobie informacje o bledzie
13.    }
14.}
15. 
16.$oValidator = new Validation_Type();
17. 
18.    

I wszystko działa. Wszystkie dziwne rzeczy dzieją się w tle. Bardzo podobny system wykorzystywany jest we frameworku Zend oraz kilku innych frameworkach. Powodzenia.

 

Pełne kody na SVN

http://php-validation.googlecode.com/svn/trunk/

 

Dodaj komentarz

Zostało: 1000 symboli


Kod antysapmowy
Odśwież