1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- EN-Revision: 19782 -->
4 <sect1 id="learning.autoloading.usage">
5 <title>Podstawowe użycie autoloadera</title>
8 Po krótkim opisie samej idei autoloadera jak i konwencji oraz celi związanych z
9 jego implementacją w Zend Framework można przejść do opisu użycia
10 <classname>Zend_Loader_Autoloader</classname>.
14 W najprostszym przypadku należy dołączyć plik z definicją klasy i uzyskać dostęp do obiektu.
15 <classname>Zend_Loader_Autoloader</classname> jest singletonem (co jest uwarunkowane
16 autoloaderem <acronym>SPL</acronym>, który jest pojedynczym zasobem) więc do uzyskania
17 jego instancji należy użyć metody <methodname>getInstance()</methodname>.
20 <programlisting language="php"><![CDATA[
21 require_once 'Zend/Loader/Autoloader.php';
22 Zend_Loader_Autoloader::getInstance();
26 Domyślnie spowoduje to automatyczne dołączanie dowolnych klas zawierających prefiks
27 przestrzeni nazw "Zend_" oraz "ZendX_" pod warunkiem, że znajdują się w katalogu zawartym w
28 <property>include_path</property>.
32 Co się dzieje w przypadku gdy wymagane jest użycie innych przestrzeni nazw? Najlepszym i
33 najłatwiejszym sposobem jest wywołanie metody <methodname>registerNamespace()</methodname>.
34 Można do niej przekazać pojedynczy prefiks przestrzeni nazw lub ich całą tablicę:
37 <programlisting language="php"><![CDATA[
38 require_once 'Zend/Loader/Autoloader.php';
39 $loader = Zend_Loader_Autoloader::getInstance();
40 $loader->registerNamespace('Foo_');
41 $loader->registerNamespace(array('Foo_', 'Bar_'));
45 Alternatywnie można skonfigurować <classname>Zend_Loader_Autoloader</classname> aby działał
46 jako autoloader awaryjny ("fallback" autoloader). To oznacza, że będzie próbował
47 działać dla każdej używanej klasy niezależnie od jej prefiksu przestrzeni nazw.
50 <programlisting language="php"><![CDATA[
51 $loader->setFallbackAutoloader(true);
55 <title>Nie należy używać autoloadera awaryjnego</title>
58 Użycie <classname>Zend_Loader_Autoloader</classname> jako autoloadera awaryjnego może
59 być kuszące ale nie jest rekomendowane.
63 Wewnętrznie <classname>Zend_Loader_Autoloader</classname> używa
64 <methodname>Zend_Loader::loadClass()</methodname> do dołączania definicji klas. Ta
65 metoda używa <methodname>include()</methodname> do załadowania danego pliku z klasą.
66 Funkcja <methodname>include()</methodname> zwraca wartość <constant>FALSE</constant>
67 w przypadku niepowodzenia a dodatkowo wysyła błąd ostrzeżenia <acronym>PHP</acronym> co
68 może prowadzić do następujących konsekwencji:
74 Jeśli włączona jest opcja <property>display_errors</property> to ostrzeżenie
75 zostanie dołączone do wyniku działania funkcji.
81 W zależności od wybranego poziomu opcji <property>error_reporting</property>
82 może powodować bałagan w logach.
88 Istnieje możliwość wyłączenia wyświetlania komunikatów błędów przez autoloader
89 (opisana w dokumentacji <classname>Zend_Loader_Autoloader</classname>) ale należy
90 pamiętać iż działa to tylko w przypadku włączenia opcji
91 <property>display_errors</property>. Plik z logami błędów i tak będzie przechowywał
92 wszystkie komunikaty. Z tego powodu zalecane jest używanie prefiksów przestrzeni nazw
93 i powiadomienie o nich autoloadera.
98 <title>Prefiksy przestrzeni nazw a przestrzenie nazw PHP</title>
101 W momencie powstawania tego dokumentu istnieje stabilna wersja
102 <acronym>PHP</acronym> 5.3. Od tego wydania <acronym>PHP</acronym> oficjalnie oferuje
103 pełne wsparcie dla przestrzeni nazw.
107 Zend Framework uprzedził <acronym>PHP</acronym> 5.3 pod tym względem.
108 Wewnątrz dokumentacji Zend Framework, jeśli jest mowa o "przestrzeniach nazw" to
109 odnosi się to do prefiksów klas wskazujących na aplikację, twórcę lub firmę.
110 Dla przykładu, wszystkie nazwy klas w Zend Framework mają prefiks "Zend_" - to jest
111 "przestrzeń nazw" używana przez firmę Zend.
115 Planowane jest wprowadzenie obsługi natywnych przestrzeni nazw <acronym>PHP</acronym>
116 do autoloadera w przyszłych wersjach Zend Framework. Będzie to możliwe od wersji 2.0.0.
121 Jeśli deweloper posiada własny autoloader (np. pochodzący z innej biblioteki, która jest
122 używana równolegle), który powinien zostać użyty z Zend Framework to można to uczynić za
123 pomocą metod klasy <classname>Zend_Loader_Autoloader</classname> o nazwach
124 <methodname>pushAutoloader()</methodname> oraz <methodname>unshiftAutoloader()</methodname>.
125 Powyższe metody dopiszą podane funkcje do listy autoloaderów (która jest uruchamiana przed
126 wewnętrznymi mechanizmami Zend Framework) odpowiednio na koniec bądź na początek.
127 Takie podejście oferuje następujące korzyści:
133 Każda z tych metod przyjmuje drugi, opcjonalny argument - prefiks przestrzeni nazw.
134 Można go użyć do wskazania aby podany autoloader był używany jedynie do dołączania
135 klas zawierających podany prefiks. Jeśli dana klasa go nie posiada to autoloader nie
136 zostanie uruchomiony - takie podejście może znacznie zwiększyć wydajność.
142 Jeśli zajdzie potrzeba manipulowania rejestrem funkcji
143 <methodname>spl_autoload()</methodname>, każdy autoloader, który stanowi
144 odwołanie do metody klasy może powodować problemy. Dzieje się tak ponieważ funkcja
145 <methodname>spl_autoload_functions()</methodname> nie zwraca tych samych instancji
146 obiektów (tylko ich kopie).
147 <classname>Zend_Loader_Autoloader</classname> nie posiada takich wad.
153 W powyższy sposób można użyć każdego poprawnego odwołania do funkcji <acronym>PHP</acronym>
156 <programlisting language="php"><![CDATA[
157 // Dołączenie funkcji 'my_autoloader', która zajmuje się klasami
158 // z prefiksem 'My_' na koniec listy autoloaderów
159 $loader->pushAutoloader('my_autoloader', 'My_');
161 // Dołączenie statycznej metody Foo_Loader::autoload(), która zajmuje
162 // się klasami z prefiksem 'Foo_' na początek listy autoloaderów
163 $loader->unshiftAutoloader(array('Foo_Loader', 'autoload'), 'Foo_');