友好错误提示页原文

Kohana3并没有像ko2默认有方法显示友好的错误页;这个快速教程将教你怎么做.原文 seen in Kohana 2; In this short guide you will learn how it is done.

Prerequisites

需要在’Kohana::init’中开启’errors’=>’TRUE’,这会将PHP原生的错误转化的更容易提交.原文 errors into exceptions which are easier to handle.

1. An Improved Exception Handler(三步走之第一步,一个改良的异常捕获方法)

我们常用的异常机制是原生的非友好,自身说明问题的(Kohana的异常机制代码如下,不翻译).原文

  1. class Kohana_Exception extends Kohana_Kohana_Exception {
  2. public static function handler(Exception $e)
  3. {
  4. if (Kohana::DEVELOPMENT === Kohana::$environment)
  5. {
  6. parent::handler($e);
  7. }
  8. else
  9. {
  10. try
  11. {
  12. Kohana::$log->add(Log::ERROR, parent::text($e));
  13. $attributes = array
  14. (
  15. 'action' => 500,
  16. 'message' => rawurlencode($e->getMessage())
  17. );
  18. if ($e instanceof HTTP_Exception)
  19. {
  20. $attributes['action'] = $e->getCode();
  21. }
  22. // Error sub-request.
  23. echo Request::factory(Route::get('error')->uri($attributes))
  24. ->execute()
  25. ->send_headers()
  26. ->body();
  27. }
  28. catch (Exception $e)
  29. {
  30. // Clean the output buffer if one exists
  31. ob_get_level() and ob_clean();
  32. // Display the exception text
  33. echo parent::text($e);
  34. // Exit with an error status
  35. exit(1);
  36. }
  37. }
  38. }
  39. }

如果我们在开发环境下就过掉(无视)它,转用其他的Kohana异常处理(机制).原文

记录错误[原文](# Log the error) 设置路由动作函数和信息(属性).[原文](# Set the route action and message attributes.) 如果一个’HTTP_Exception’抛出,就重写动作,显示相关错误代码(当然,是友好).[原文](# If a HTTP_Exception was thrown, then override the action with the error code.) 抛出一个内部子请求.[原文](# Fire off an internal sub-request.)

动作会被当作HTTP response代码.默认的是500(服务器错误),除非一个’HTTP_Response_Exception’抛出.原文 unless a HTTP_Response_Exception was thrown.)

因此这个(如下的代码):原文

  1. throw new HTTP_Exception_404(':file does not exist', array(':file' => 'Gaia'));

会显示一个友好的404错误页,这个(如下代码):原文

  1. throw new Kohana_Exception('Directory :dir must be writable',
  2. array(':dir' => Debug::path(Kohana::$cache_dir)));

将显示一个500错误页面.原文

The Route(路由配置) Route::set(‘error’, ‘error/(/)’, array(‘action’ => ‘[0-9]++’, ‘message’ => ‘.+’)) ->defaults(array( ‘controller’ => ‘error_handler’ ));

2. The Error Page Controller (三步之第二步,错误页面控制器)

  1. public function before()
  2. {
  3. parent::before();
  4. $this->template->page = URL::site(rawurldecode(Request::$initial->uri()));
  5. // Internal request only!
  6. if (Request::$initial !== Request::$current)
  7. {
  8. if ($message = rawurldecode($this->request->param('message')))
  9. {
  10. $this->template->message = $message;
  11. }
  12. }
  13. else
  14. {
  15. $this->request->action(404);
  16. }
  17. $this->response->status((int) $this->request->action());
  18. }

1设置模板显示变量’page’是为了让用户明白自己的请求是什么.这样做的目仅为了显示.原文 2.如果只是内部请求,给’message’变量赋值并显示给用户.原文 3.否则的话使用404动作.用户可以更巧妙的设置自己的信息,比如’error/404/email%20your%20login%20information%20to%20hacker%40google.com'.[原文](#3. Otherwise use the 404 action. Users could otherwise craft their own error messages, eg:error/404/email%20your%20login%20information%20to%20hacker%40google.com`)

  1. public function action_404()
  2. {
  3. $this->template->title = '404 Not Found';
  4. // Here we check to see if a 404 came from our website. This allows the
  5. // webmaster to find broken links and update them in a shorter amount of time.
  6. if (isset ($_SERVER['HTTP_REFERER']) AND strstr($_SERVER['HTTP_REFERER'], $_SERVER['SERVER_NAME']) !== FALSE)
  7. {
  8. // Set a local flag so we can display different messages in our template.
  9. $this->template->local = TRUE;
  10. }
  11. // HTTP Status code.
  12. $this->response->status(404);
  13. }
  14. public function action_503()
  15. {
  16. $this->template->title = 'Maintenance Mode';
  17. }
  18. public function action_500()
  19. {
  20. $this->template->title = 'Internal Server Error';
  21. }

你应注意到每个方法都是在’HTTP response’ 代码后命名,并设置请求的代码.原文

3. Conclusion (三步走之第三步,结局)

搞定!现在显示一个友好的错误页面是相当容易的啦(就像下面这样):原文

  1. throw new HTTP_Exception_503('The website is down');(这会抛出503错误,内容是,站点挂了.)