Pseudo-przestrzenie nazw a'la PEAR |
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
Prosta ideaW 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:
W takiej sytucji do klasy Data mielibyśmy taką ścieżkę:
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 nazwW PHP5 możemy uzyskać bardzo podobny efekt. Załóżmy, że mamy taką strukturę katalogów ("pakietów"):
Jeśli chcemy zatem załączyć odpowiednie pliki stosujemy:
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 PEARSkoro 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:
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:
W takiej sytuacji należy jeszcze zmienić definicję klasy:
na
Przy załączaniu robimy identycznie jak poprzednio:
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 klasSkoro w nazwie skryptu, definiujemy jego położenie, to dlaczego nie wykorzystać odpowiednio autoloadera?
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/
|