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