Zend_Loader.xml 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. <sect1 id="zend.loader.load">
  2. <title> 动态加载文件和类 </title>
  3. <para>
  4. Zend_Loader类可以帮助你动态加载文件。
  5. </para>
  6. <tip>
  7. <title>Zend_Loader vs. require_once()</title>
  8. <para>
  9. <code>Zend_Loader</code> 最适合于加载的文件名是变量的情况(例如你要加载的文件的名称来自于用户的输入或者某个方法的参数)。如果你加载的文件名或类名是一个常量(即确定的文件,如/lib/test.php),则使用 <code>Zend_Loader</code> 并不比传统的PHP函数 <ulink url="http://php.net/require_once"><code>require_once()</code></ulink>有什么优势。
  10. </para>
  11. </tip>
  12. <sect2 id="zend.loader.load.file">
  13. <title> 加载文件 </title>
  14. <para>
  15. 静态方法 <code>Zend_Loader::loadFile()</code> 加载PHP文件,被加载的文件可包含任何 PHP 代码。它其实是将PHP的<ulink url="http://php.net/include"><code>include()</code></ulink>函数封装而成的一个静态方法。当包含文件失败时,会抛出异常Zend_Exception,例如指定的文件不存在。
  16. </para>
  17. <example id="zend.loader.load.file.example">
  18. <title>loadFile() 方法范例 </title>
  19. <programlisting role="php"><![CDATA[
  20. Zend_Loader::loadFile($filename, $dirs=null, $once=false);
  21. ]]>
  22. </programlisting>
  23. </example>
  24. <para>
  25. <code>$filename</code>参数指定需要加载的文件,注意<code>$filename</code>不需要指定任何路径,只需要文件名即可。ZF会对文件作安全性检查。<code>$filename</code> 只能由字母,数字,连接符-,下划线_及英文句号.组成(半角)。<code>$dirs</code>参数则不限,可以使用中文等。
  26. </para>
  27. <para>
  28. <code>$dirs</code> 参数用来指定文件所在目录,可以是一个字符串或者数组。如果为 <code>NULL</code>,则程序将会到系统的 <code>include_path</code> 下寻找文件是否存在(include_path可在php.ini中设置--Haohappy注),如果是字符串或数组,则会到指定的目录下去找,然后才是 <code>include_path</code>。
  29. </para>
  30. <para>
  31. <code>$once</code> 参数为布尔类型,如果为 <code>TRUE</code>,<code>Zend_Loader::loadFile()</code> 使用 PHP 函数 <ulink url="http://php.net/include"><code>include_once()</code></ulink> 加载文件,否则就是 PHP 函数 <ulink url="http://php.net/include_once"><code>include()</code></ulink>。(本参数只能是true或false,两者区别就和include()和include_once()的区别一样。)
  32. </para>
  33. </sect2>
  34. <sect2 id="zend.loader.load.class">
  35. <title> 加载类 </title>
  36. <para>
  37. 静态方法<code>Zend_Loader::loadClass($class, $dirs)</code>用来加载一个 PHP 类文件,该文件名格式为“$className.php”(也就是说加载的文件名称必须和文件中的类同名)。loadClass()会检查文件中的类是否存在。
  38. </para>
  39. <example id="zend.loader.load.class.example">
  40. <title>Example of loadClass() method</title>
  41. <programlisting role="php"><![CDATA[
  42. Zend_Loader::loadClass('Container_Tree',
  43. array(
  44. '/home/production/mylib',
  45. '/home/production/myapp'
  46. )
  47. );
  48. ]]>
  49. </programlisting>
  50. </example>
  51. <para>
  52. 类名将会根据下划线(作为目录分隔线)对应到相应目录下的PHP文件,并加上'.php',比如Container_Tree会指向Container\\Tree.php。
  53. </para>
  54. <para>
  55. 如果<code>$dirs</code>是一个字符串或数组, <code>Zend_Loader::loadClass()</code>会根据顺序查找相应目录,并加载第一个匹配的文件。如果文件不存在,则会查找 <code>inculde_path</code> 指定的目录。
  56. </para>
  57. <para>
  58. 如果文件不存在或者文件中相应的类不存在,那么 <code>Zend_Loader::loadClass()</code> 就会抛出一个 <code>Zend_Exception</code> 异常。
  59. </para>
  60. <para>
  61. <code>Zend_Loader::loadFile()</code> 用来加载文件,所以类名中只能包含字母数字、连接符('-')、下划线('_')和句点('.')。
  62. </para>
  63. </sect2>
  64. <sect2 id="zend.loader.load.isreadable">
  65. <title> 判定某个文件是否可读 </title>
  66. <para>
  67. 静态方法<code>Zend_Loader::isReadable($pathname)</code>判定某个文件是否存在并可读,可读则返回 <code>TRUE</code> ,否则返回 <code>FALSE</code>。
  68. </para>
  69. <example id="zend.loader.load.isreadable.example">
  70. <title>isReadable()示例:</title>
  71. <programlisting role="php"><![CDATA[
  72. if (Zend_Loader::isReadable($filename)) {
  73. // do something with $filename
  74. }
  75. ]]>
  76. </programlisting>
  77. </example>
  78. <para>
  79. <code>$filename</code>参数指定了要检查的文件名,包括路径信息。这个方法是将 PHP 函数<ulink url="http://php.net/is_readable"><code>is_readable()</code></ulink>封装而成的,<code>is_readable()</code> 不会自动查找 <code>include_path</code> 下的文件,而 <code>Zend::isReadable()</code> 可以。
  80. </para>
  81. </sect2>
  82. <sect2 id="zend.loader.load.autoload">
  83. <title> 使用 Autoloader</title>
  84. <para>
  85. <code>Zend_Loader</code> 类包括一个可以用 PHP SPL autoloader 注册的方法。<code>Zend_Loader::autoload()</code> 是 callback 方法。为方便起见,<code>Zend_Loader</code> 提供 <code>registerAutoload()</code> 函数注册它的 <code>autoload()</code> 方法。如果 <code>spl_autoload</code> 扩展不在你的 PHP 环境中,那么 <code>registerAutoload()</code> 方法将抛出 <code>Zend_Exception</code>。
  86. </para>
  87. <example id="zend.loader.load.autoload.example">
  88. <title> 注册 autoloader callback 方法范例 </title>
  89. <programlisting role="php"><![CDATA[
  90. Zend_Loader::registerAutoload();
  91. ]]>
  92. </programlisting>
  93. </example>
  94. <para>
  95. 注册 Zend Framework autoload callback 后,可以不需要显式加载就可以从 Zend Framework 引用那些类。当应用一个类,<code>autoload()</code> 方法自动地使用 <code>Zend_Loader::loadClass()</code> 。
  96. </para>
  97. <para>
  98. 如果继承 <code>Zend_Loader</code> 类,可以给 <code>registerAutoload()</code> 一个可选的参数通过注册一个 <code>autoload()</code> 方法来指定类。
  99. </para>
  100. <example id="zend.loader.load.autoload.example-extended">
  101. <title> 从继承类注册 autoload callback 方法范例 </title>
  102. <para>
  103. 因为在 PHP 中静态函数引用的语义,你必须实现 <code>loadClass()</code> 和 <code>autoload()</code>,<code>autoload()</code> 必须调用 <code>self::loadClass()</code>。如果 <code>autoload()</code> 方法代表它的父类调用 <code>self::loadClass()</code>,那么它调用在父类中的方法,而不是子类中。
  104. </para>
  105. <programlisting role="php"><![CDATA[
  106. class My_Loader extends Zend_Loader
  107. {
  108. public static function loadClass($class, $dirs = null)
  109. {
  110. parent::loadClass($class, $dirs);
  111. }
  112. public static function autoload($class)
  113. {
  114. try {
  115. self::loadClass($class);
  116. return $class;
  117. } catch (Exception $e) {
  118. return false;
  119. }
  120. }
  121. }
  122. Zend_Loader::registerAutoload('My_Loader');
  123. ]]>
  124. </programlisting>
  125. </example>
  126. <para>
  127. 你可以删除 autoload callback,<code>registerAutoload()</code> 有个可选的第二个参数,缺省为 <code>true</code> 。如果这个参数是 <code>false</code>, 那么 autoload callback 从 SPL autoload 栈里 unregistered 掉而不是注册。
  128. </para>
  129. </sect2>
  130. </sect1>
  131. <!--
  132. vim:se ts=4 sw=4 et:
  133. -->