autoloading-usage.xml 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 24249 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="learning.autoloading.usage">
  5. <title>Grundsätzliche Verwendung von Autoloadern</title>
  6. <para>
  7. Jetzt da wir verstehen was Autoloading ist, und was die Ziele und das Design von Zend
  8. Framework's Autoloading Lösung sind, schauen wir und an wie
  9. <classname>Zend_Loader_Autoloader</classname> verwendet wird.
  10. </para>
  11. <para>
  12. Im einfachsten Fall wird die Klasse einfach mit "require" verwendet und anschließend
  13. instanziert. Da <classname>Zend_Loader_Autoloader</classname> ein Singleton ist (aus dem
  14. Grund da auch der <acronym>SPL</acronym> Autoloader eine einzelne Ressource ist) verwenden
  15. wir <methodname>getInstance()</methodname> um eine Instanz zu erhalten.
  16. </para>
  17. <programlisting language="php"><![CDATA[
  18. require_once 'Zend/Loader/Autoloader.php';
  19. Zend_Loader_Autoloader::getInstance();
  20. ]]></programlisting>
  21. <para>
  22. Standardmäßig erlaubt dies das Laden jeder Klasse mit dem Klassen Namespace Präfix "Zend_"
  23. oder "ZendX_", solange Sie im eigenen <property>include_path</property> liegen.
  24. </para>
  25. <para>
  26. Was passiert wenn man andere Namespace Präfix verwenden will? Der beste und einfachste Weg
  27. ist der Aufruf der <methodname>registerNamespace()</methodname> Methode auf der Instanz. Man
  28. kann einen einzelnen Namespace Präfix übergeben, oder ein Array von Ihnen:
  29. </para>
  30. <programlisting language="php"><![CDATA[
  31. require_once 'Zend/Loader/Autoloader.php';
  32. $loader = Zend_Loader_Autoloader::getInstance();
  33. $loader->registerNamespace('Foo_');
  34. $loader->registerNamespace(array('Foo_', 'Bar_'));
  35. ]]></programlisting>
  36. <para>
  37. Alternativ kann man <classname>Zend_Loader_Autoloader</classname> sagen das es als
  38. "fallback" Autoloader arbeiten soll. Das bedeutet das er versuchen wird jede Klasse
  39. aufzulösen unabhängig vom Namespace Präfix.
  40. </para>
  41. <programlisting language="php"><![CDATA[
  42. $loader->setFallbackAutoloader(true);
  43. ]]></programlisting>
  44. <warning>
  45. <title>Ein Fallback Autloader sollte nicht verwendet werden</title>
  46. <para>
  47. Wärend es nützlich erscheint <classname>Zend_Loader_Autoloader</classname> als Fallback
  48. Autoloader zu verwenden, empfehlen wir diese Praxis nicht.
  49. </para>
  50. <para>
  51. Intern verwendet <classname>Zend_Loader_Autoloader</classname>
  52. <methodname>Zend_Loader::loadClass()</methodname> um Klassen zu laden. Diese Methode
  53. verwendet <methodname>include()</methodname> um zu versuchen die gegebene Klassendatei
  54. zu laden. <methodname>include()</methodname> gibt ein boolsches
  55. <constant>FALSE</constant> zurück wenn es nicht erfolgreich war -- löst aber auch eine
  56. <acronym>PHP</acronym> Warnung aus. Der letztere Fakt kann zu einigen Problemen führen:
  57. </para>
  58. <itemizedlist>
  59. <listitem>
  60. <para>
  61. Wenn <property>display_errors</property> aktiviert ist, ist die Warnung in der
  62. Ausgabe enthalten.
  63. </para>
  64. </listitem>
  65. <listitem>
  66. <para>
  67. Abhängig vom <property>error_reporting</property> Level den man ausgewählt hat,
  68. könnte es auch die Logs zuschütten.
  69. </para>
  70. </listitem>
  71. </itemizedlist>
  72. <para>
  73. Man kann die Fehlermeldungen unterdrücken (die Dokumentation von
  74. <classname>Zend_Loader_Autoloader</classname> gibt Details), aber man sollte beachten
  75. die Unterdrückung nur relevant ist wenn <property>display_errors</property> aktiviert
  76. ist; das Fehler Log wird die Meldung immer zeigen. Aus diesem Grund empfehlen wir die
  77. Namespace Präfixe welche der Autoloader behandeln soll, immer zu konfigurieren.
  78. </para>
  79. </warning>
  80. <note>
  81. <title>Namespace Präfixe vs PHP Namespaces</title>
  82. <para>
  83. Wärend dies geschrieben wurde, wurde <acronym>PHP</acronym> 5.3 herausgebracht. Mit
  84. dieser Version unterstützt <acronym>PHP</acronym> jetzt offiziell Namespaces.
  85. </para>
  86. <para>
  87. Trotzdem ist Zend Framework auf vor <acronym>PHP</acronym> 5.3 im Einsatz, und deshalb
  88. auch Namespaces. Wenn wir im Zend Framework auf "Namespaces" verweisen, verweisen wir
  89. auf eine Praxis bei der Klassen ein Hersteller "Namespace" vorangestellt wird. Als
  90. Beispiel wird allen Zend Framework Klassen "Zend_" vorangestellt -- das ist unser
  91. Hersteller "Namespace".
  92. </para>
  93. <para>
  94. Zend Framework plant die native Unterstützung von <acronym>PHP</acronym> Namespaces im
  95. Autoloader in zukünftigen Versionen, und seine eigene Bibliothek wird Namespaces
  96. beginnend mit Version 2.0.0 verwenden.
  97. </para>
  98. </note>
  99. <para>
  100. Wenn man eigene Autoloader hat, die man mit Zend Framework verwenden will -- möglicherweise
  101. einen Autoloader von einer anderen Bibliothek die man verwendet -- kann man das mit
  102. <classname>Zend_Loader_Autoloader</classname>'s <methodname>pushAutoloader()</methodname>
  103. und <methodname>unshiftAutoloader()</methodname> Methoden durchführen. Diese Methoden
  104. stellen Autoloader einer Kette voran welche aufgerufen wird, oder hängen Sie an, bevor Zend
  105. Framework's interner autoloading Mechanismus ausgeführt wird. Dieser Ansatz bietet die
  106. folgenden Vorteile:
  107. </para>
  108. <itemizedlist>
  109. <listitem>
  110. <para>
  111. Jede Methode nimmt ein zweites optionales Argument entgegen, einen Klassen Namespace
  112. Präfix. Dieser kann verwendet werden um anzuzeigen das der angegebene Autoloader nur
  113. verwendet werden soll wenn nach Klassen mit dem angegebenen Klassenpräfix gesehen
  114. wird. Wenn die aufgelöste Klasse diesen Präfix nicht hat, wird der Autoloader
  115. übergangen -- was zu Verbesserungen der Geschwindigkeit führen kann.
  116. </para>
  117. </listitem>
  118. <listitem>
  119. <para>
  120. Wenn man <methodname>spl_autoload()</methodname>'s Registry verändern muss, können
  121. alle Autoloader welche Callbacks sind und auf Methoden einer Instanz sind, Probleme
  122. verursachen da <methodname>spl_autoload_functions()</methodname> nicht exakt die
  123. gleichen Callbacks zurückgibt. <classname>Zend_Loader_Autoloader</classname> hat
  124. keine entsprechenden Begrenzungen.
  125. </para>
  126. </listitem>
  127. </itemizedlist>
  128. <para>
  129. Autoloader welche auf diesem Weg gemanaged werden können alle gültigen
  130. <acronym>PHP</acronym> Callbacks sein.
  131. </para>
  132. <programlisting language="php"><![CDATA[
  133. // Die Funktion 'my_autoloader' dem Stack voranstellen,
  134. // um Klassen mit dem Präfix 'My_' zu managen:
  135. $loader->pushAutoloader('my_autoloader', 'My_');
  136. // Die statische Methode Foo_Loader::autoload() dem Stack anhängen,
  137. // um Klassen mit dem Präfix 'Foo_' zu managen:
  138. $loader->unshiftAutoloader(array('Foo_Loader', 'autoload'), 'Foo_');
  139. ]]></programlisting>
  140. </sect1>