autoloading-usage.xml 7.4 KB

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