Zend_Controller-Plugins-ErrorHandler.xml 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. <sect3 id="zend.controller.plugins.standard.errorhandler">
  2. <title>Zend_Controller_Plugin_ErrorHandler</title>
  3. <para>
  4. <code>Zend_Controller_Plugin_ErrorHandler</code>提供了一个活动的插件,用来处理从程序抛出的异常,包括那些从缺控制器或动作的来的结果;它是一个列在<link linkend="zend.controller.exceptions">MVC Exceptions section</link>里的方法的一个替代。
  5. </para>
  6. <para>
  7. 插件的基本目标是:
  8. </para>
  9. <itemizedlist>
  10. <listitem>
  11. <para>
  12. 监视由于缺失控制器或动作方法而产生的异常
  13. </para>
  14. </listitem>
  15. <listitem>
  16. <para>监视动作控制器里产生的异常</para>
  17. </listitem>
  18. </itemizedlist>
  19. <para>
  20. 换句话说,<code>ErrorHandler</code> 插件设计用来处理HTTP 404 类型的错误(找不到页面)和 500 类型错误(内部错误)。它不打算抓取有其它插件或路由产生的异常。
  21. </para>
  22. <para>
  23. 缺省地,在缺省模块中,<code>Zend_Controller_Plugin_ErrorHandler</code>将转发给<code>ErrorController::errorAction()</code>。你可以通过使用在插件中不同的访问器给它们设置替代的值:
  24. </para>
  25. <itemizedlist>
  26. <listitem>
  27. <para>
  28. <code>setErrorHandlerModule()</code> 设置控制器模块来使用。
  29. </para>
  30. </listitem>
  31. <listitem>
  32. <para>
  33. <code>setErrorHandlerController()</code> 设置控制器来用。
  34. </para>
  35. </listitem>
  36. <listitem>
  37. <para>
  38. <code>setErrorHandlerAction()</code> 设置控制器动作来用。
  39. </para>
  40. </listitem>
  41. <listitem>
  42. <para>
  43. <code>setErrorHandler()</code>接受联合数组,它可以包含任何键,如'module'、 'controller' 或 'action',以及要给它们设置的合适的值。
  44. </para>
  45. </listitem>
  46. </itemizedlist>
  47. <para>
  48. 另外,你可以传递一个可选的联合数组给可以代理<code>setErrorHandler()</code>的构造函数。
  49. </para>
  50. <para>
  51. <code>Zend_Controller_Plugin_ErrorHandler</code>注册一个<code>postDispatch()</code>钩子和检查注册在<link linkend="zend.controller.response">响应对象</link>里的异常。如果发现有异常,它试图转发给注册的错误处理器(handler)动作。
  52. </para>
  53. <para>
  54. 如果在派遣错误处理器时发生异常,这插件将告诉前端控制器抛出异常,并重新抛出和带响应对象注册的最后一个异常。
  55. </para>
  56. <sect4 id="zend.controller.plugins.standard.errorhandler.fourohfour">
  57. <title>使用 ErrorHandler 作为一个 404 处理器(handler)</title>
  58. <para>
  59. 因为<code>ErrorHandler</code>插件不仅抓取程序错误,而且也抓取在控制器链里的由于缺失控制器类和/或动作方法而产生的错误,它可以用作一个404处理器。这样做,需要让错误控制器检查异常类型。
  60. </para>
  61. <para>
  62. 异常的抓取被记录在一个对象里,这个对象注册在请求里。使用<code>Zend_Controller_Action::_getParam('error_handler')</code>来读取它:
  63. </para>
  64. <programlisting role="php"><![CDATA[
  65. class ErrorController extends Zend_Controller_Action
  66. {
  67. public function errorAction()
  68. {
  69. $errors = $this->_getParam('error_handler');
  70. }
  71. }
  72. ]]>
  73. </programlisting>
  74. <para>
  75. 一旦有错误对象,可通过<code>$errors->type</code>来获得类型。它将是下面其中之一:
  76. </para>
  77. <itemizedlist>
  78. <listitem>
  79. <para>
  80. <code>Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER</code>,指示控制器没有被发现。
  81. </para>
  82. </listitem>
  83. <listitem>
  84. <para>
  85. <code>Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION</code>,指示请求动作没有被发现。
  86. </para>
  87. </listitem>
  88. <listitem>
  89. <para>
  90. <code>Zend_Controller_Plugin_ErrorHandler::EXCEPTION_OTHER</code>,指示其它异常。
  91. </para>
  92. </listitem>
  93. </itemizedlist>
  94. <para>
  95. 然后可以测试头两个类型中的任意一个,并且,如果这样,显示一个404页面:
  96. </para>
  97. <programlisting role="php"><![CDATA[
  98. class ErrorController extends Zend_Controller_Action
  99. {
  100. public function errorAction()
  101. {
  102. $errors = $this->_getParam('error_handler');
  103. switch ($errors->type) {
  104. case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
  105. case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
  106. // 404 error -- controller or action not found
  107. $this->getResponse()
  108. ->setRawHeader('HTTP/1.1 404 Not Found');
  109. // ... get some output to display...
  110. break;
  111. default:
  112. // application error; display error page, but don't
  113. // change status code
  114. break;
  115. }
  116. }
  117. }
  118. ]]>
  119. </programlisting>
  120. <para>
  121. 最后,你可以读取异常,这个异常由错误管理器通过抓取<code>error_handler</code>对象的<code>exception</code>属性来触发的:
  122. </para>
  123. <programlisting role="php">
  124. <![CDATA[
  125. public function errorAction()
  126. {
  127. $errors = $this->_getParam('error_handler');
  128. switch ($errors->type) {
  129. case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
  130. case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
  131. // 404 error -- controller or action not found
  132. $this->getResponse()
  133. ->setRawHeader('HTTP/1.1 404 Not Found');
  134. // ... get some output to display...
  135. break;
  136. default:
  137. // application error; display error page, but don't change
  138. // status code
  139. // ...
  140. // Log the exception:
  141. $exception = $errors->exception;
  142. $log = new Zend_Log(
  143. new Zend_Log_Writer_Stream(
  144. '/tmp/applicationException.log'
  145. )
  146. );
  147. $log->debug($exception->getMessage() . "\n" .
  148. $exception->getTraceAsString());
  149. break;
  150. }
  151. }
  152. ]]>
  153. </programlisting>
  154. </sect4>
  155. <sect4 id="zend.controller.plugins.standard.errorhandler.buffer">
  156. <title>处理以前呈现的(rendered)输出</title>
  157. <para>
  158. 如果你在一个请求里派遣多个动作,或者你的动作对<code>render()</code>做多次调用,很可能响应对象已经有存储在它里面的内容。这可以导致呈显期望的内容和错误的内容的混合体。
  159. </para>
  160. <para>
  161. 如果你希望呈现错误内嵌到这样的页面,不需要修改。如果你不希望呈现这样的内容,你应该在呈现任何视图之前清除响应体:
  162. </para>
  163. <programlisting role="php"><![CDATA[
  164. $this->getResponse()->clearBody();
  165. ]]>
  166. </programlisting>
  167. </sect4>
  168. <sect4 id="zend.controller.plugins.standard.errorhandler.examples">
  169. <title>插件用法示例</title>
  170. <example id="zend.controller.plugins.standard.errorhandler.examples.example-1">
  171. <title>Standard usage</title>
  172. <programlisting role="php"><![CDATA[
  173. $front = Zend_Controller_Front::getInstance();
  174. $front->registerPlugin(new Zend_Controller_Plugin_ErrorHandler());
  175. ]]>
  176. </programlisting>
  177. </example>
  178. <example id="zend.controller.plugins.standard.errorhandler.examples.example-2">
  179. <title>Setting a different error handler</title>
  180. <programlisting role="php"><![CDATA[
  181. $front = Zend_Controller_Front::getInstance();
  182. $front->registerPlugin(new Zend_Controller_Plugin_ErrorHandler(array(
  183. 'module' => 'mystuff',
  184. 'controller' => 'static',
  185. 'action' => 'error'
  186. )));
  187. ]]>
  188. </programlisting>
  189. </example>
  190. <example id="zend.controller.plugins.standard.errorhandler.examples.example-3">
  191. <title>Using accessors</title>
  192. <programlisting role="php"><![CDATA[
  193. $plugin = new Zend_Controller_Plugin_ErrorHandler();
  194. $plugin->setErrorHandlerModule('mystuff')
  195. ->setErrorHandlerController('static')
  196. ->setErrorHandlerAction('error');
  197. $front = Zend_Controller_Front::getInstance();
  198. $front->registerPlugin($plugin);
  199. ]]>
  200. </programlisting>
  201. </example>
  202. </sect4>
  203. <sect4 id="zend.controller.plugins.standard.errorhandler.controllerexamples">
  204. <title>错误控制器示例</title>
  205. <para>
  206. 为了使用错误处理器插件,你需要错误控制器。下面是个简单的例子。
  207. </para>
  208. <programlisting role="php"><![CDATA[
  209. class ErrorController extends Zend_Controller_Action
  210. {
  211. public function errorAction()
  212. {
  213. $errors = $this->_getParam('error_handler');
  214. switch ($errors->type) {
  215. case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
  216. case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
  217. // 404 error -- controller or action not found
  218. $this->getResponse()->setRawHeader('HTTP/1.1 404 Not Found');
  219. $content =<<<EOH
  220. <h1>Error!</h1>
  221. <p>The page you requested was not found.</p>
  222. EOH;
  223. break;
  224. default:
  225. // application error
  226. $content =<<<EOH
  227. <h1>Error!</h1>
  228. <p>An unexpected error occurred. Please try again later.</p>
  229. EOH;
  230. break;
  231. }
  232. // Clear previous content
  233. $this->getResponse()->clearBody();
  234. $this->view->content = $content;
  235. }
  236. }
  237. ]]>
  238. </programlisting>
  239. </sect4>
  240. </sect3>
  241. <!--
  242. vim:se ts=4 sw=4 et:
  243. -->