2011-09-16 39 views
2

我试图按照此处的说明操作:http://kohanaframework.org/3.0/guide/kohana/tutorials/error-pages但由于某种原因,我无法捕获HTTP_Exception_404我仍然收到一个丑陋的错误页面,而不是我的自定义页面。如何在Kohana中捕获HTTP_Exception_404错误

此外,当我输入URL错误/ 404 /消息,我得到一个丑陋的Kohana HTTP 404错误消息。

这里是文件结构:

  • 模块
      • 的init.php
        • 控制器
          • error_handler.php
        • http_response_exception.php
        • kohana.php
      • 意见
        • error.php

代码:

的init.php:

<?php defined('SYSPATH') or die('No direct access'); 

Route::set('error', 'error/<action>(/<message>)', array('action' => '[0-9]++', 'message' => '.+')) 
    ->defaults(array(
      'controller' => 'error_handler' 
)); 

http_response_exception.php:

<?php defined('SYSPATH') or die('No direct access'); 

class HTTP_Response_Exception extends Kohana_Exception { 


    public static function exception_handler(Exception $e) 
    { 

      if (Kohana::DEVELOPMENT === Kohana::$environment) 
      { 
        Kohana_Core::exception_handler($e); 
      } 
      else 
      { 
        Kohana::$log->add(Kohana::ERROR, Kohana::exception_text($e)); 

        $attributes = array 
        (
          'action' => 500, 
          'message' => rawurlencode($e->getMessage()), 
        ); 

        if ($e instanceof HTTP_Response_Exception) 
        { 
          $attributes['action'] = $e->getCode(); 
        } 

        // Error sub-request. 
        echo Request::factory(Route::url('error', $attributes)) 
          ->execute() 
          ->send_headers() 
          ->response; 
      } 
    } 
} 

kohana.php:

<?php defined('SYSPATH') or die('No direct script access.'); 

class Kohana extends Kohana_Core 
{ 

    /** 
    * Redirect to custom exception_handler 
    */ 
    public static function exception_handler(Exception $e) 
    { 
      Error::exception_handler($e); 
    } 

} // End of Kohana 

error_handler.php:

<?php defined('SYSPATH') or die('No direct access'); 

class Controller_Error_handler extends Controller { 

    public function before() 
    { 
      parent::before(); 

      $this->template = View::factory('template/useradmin'); 
      $this->template->content = View::factory('error'); 

      $this->template->page = URL::site(rawurldecode(Request::$instance->uri)); 

      // Internal request only! 
      if (Request::$instance !== Request::$current) 
      { 
        if ($message = rawurldecode($this->request->param('message'))) 
        { 
          $this->template->message = $message; 
        } 
      } 
      else 
      { 
        $this->request->action = 404; 
      } 
    } 

    public function action_404() 
    { 
      $this->template->title = '404 Not Found'; 

      // Here we check to see if a 404 came from our website. This allows the 
      // webmaster to find broken links and update them in a shorter amount of time. 
      if (isset ($_SERVER['HTTP_REFERER']) AND strstr($_SERVER['HTTP_REFERER'], $_SERVER['SERVER_NAME']) !== FALSE) 
      { 
        // Set a local flag so we can display different messages in our template. 
        $this->template->local = TRUE; 
      } 

      // HTTP Status code. 
      $this->request->status = 404; 
    } 

    public function action_503() 
    { 
      $this->template->title = 'Maintenance Mode'; 
      $this->request->status = 503; 
    } 

    public function action_500() 
    { 
      $this->template->title = 'Internal Server Error'; 
      $this->request->status = 500; 
    } 

} // End of Error_handler 

我真的不明白我做错了什么。预先感谢您的帮助。

回答

2

一个很长一段时间后的搜索我终于找到了解决我的小问题。

这里是如何使用的Kohana 3.2加载自己的自定义错误页一步步教程:

  1. 更改环境变量的自举。

在这里,你有多种选择:

一个。做他们所说的documentation of the bootstrap.php

/** 
* Set the environment status by the domain. 
*/ 

if (strpos($_SERVER['HTTP_HOST'], 'kohanaphp.com') !== FALSE) 
{ 
    // We are live! 
    Kohana::$environment = Kohana::PRODUCTION; 

    // Turn off notices and strict errors 
    error_reporting(E_ALL^E_NOTICE^E_STRICT); 
} 

b。或者仅添加那些没有“if”的两条线:

Kohana::$environment = Kohana::PRODUCTION; 
error_reporting(E_ALL^E_NOTICE^E_STRICT); 

c。我还没有尝试这种方式,但在新的bootstrap.php你有这样的代码:

/** 
* Set Kohana::$environment if a 'KOHANA_ENV' environment variable has been supplied. 
* 
* Note: If you supply an invalid environment name, a PHP warning will be thrown 
* saying "Couldn't find constant Kohana::<INVALID_ENV_NAME>" 
*/ 
if (isset($_SERVER['KOHANA_ENV'])) 
{ 
    Kohana::$environment = constant('Kohana::'.strtoupper($_SERVER['KOHANA_ENV'])); 
} 

我认为你可以给值“生产”到“$ _ SERVER [‘KOHANA_ENV’]”这些行前。

再次,就像我说过我没有尝试过,但它应该工作。

我个人刚刚注释掉了这些代码行。

2现在您需要在“ini.php”文件或“bootstra.php”文件中添加一些配置。

<?php defined('SYSPATH') or die('No direct script access.'); 

/** 
* Turn errors into exceptions. 
*/ 
Kohana::$errors = true; 

/** 
* Custom exception handler. 
*/ 
restore_exception_handler(); 
set_exception_handler(array('Exception_Handler', 'handler')); 

/** 
* Error route. 
*/ 
Route::set('error', 'error/<action>(/<message>)', array('action' => '[0-9]++', 'message' => '.+')) 
->defaults(array(
    'controller' => 'exception_handler' 
)); 

这是什么失踪,并使其很难。其余的,你可以轻松地按照Kohana3.2文档,或者你可以得到我添加到GitHub中的回购模块:https://github.com/jnbdz/Kohana-error

+0

嗨,我用你的模块从GitHub创建自定义错误,但我仍然无法使它的工作。你可以帮我吗? –

+0

在Stackoverflow上发布您的问题,并将其链接到此处我会尽力帮助您。 – jnbdz

+0

谢谢,这里是[我的问题的链接](http://stackoverflow.com/questions/19971897/custom-error-page-cant-get-into-handler) –

0

每个下划线都是类名称中的目录分隔符。所以在命名你的班级Http_Response_Exception时,班级应该在classes/http/response/exception.php。否则,Kohana的自动加载器将无法找到该课程。

编辑

嗯,好像文档是错误的在这方面。 classes/http_response_exception.php没有意义。

+0

没有仍然没有工作。 – jnbdz

+0

嗯,如果您处于开发环境中,您仍然会看到Kohana提供的正常错误页面。是否将'Kohana :: DEVELOPMENT === Kohana :: $ environment'更改为'Kohana :: DEVELOPMENT!== Kohana :: $ environment'显示自定义错误页面? – Luwe

+0

Nop它不会改变任何东西。 – jnbdz

2

首先,您需要确保将模块加载到应用程序/引导程序的模块部分中,以加载模块。像这样

Kohana::modules(array(
'my'=>MODPATH.'my' 
) 
); 

你提到的直接到网址为你的错误处理程序控制器的事实PHP文件触发一个404错误,让我觉得你的模块尚未加载。

我还会提出一些更改。

http_response_exception.php不需要扩展Kohana_Exception,因为这个类不是一个例外,而是一个异常处理程序。沿着同样的路线,更合适的类名可能是Exception_Handler,因为类不代表异常,而是处理它们。其次,由于你如何命名这个文件,它应该位于modules/my/classes/http/response/exception.php中。除此之外,这个类的代码看起来没问题。

同样,由于您如何命名您的控制器,它应该被定位和命名有点不同。它移动到模块/我的/班/控制器/错误/ handler.php

记得在一个类名下划线意味着一个新的目录,按照http://kohanaframework.org/3.2/guide/kohana/conventions

最后,我不认为你真的需要在这里扩展Kohana_Core类,而只需注册自己的自定义异常处理程序。您可以在任何应用程序的引导文件中注册自定义异常处理程序,或者与下面的通用代码的模块的初始化文件:

set_exception_handler(array('Exception_Handler_Class', 'handle_method')); 

这里有一个客户异常处理程序我用,这是非常类似于你:

<?php defined('SYSPATH') or die('No direct script access.'); 

class Exception_Handler { 

public static function handle(Exception $e) 
{ 
    $exception_type = strtolower(get_class($e)); 
    switch ($exception_type) 
    { 
     case 'http_exception_404': 
      $response = new Response; 
      $response->status(404); 
      $body = Request::factory('site/404')->execute()->body(); 
      echo $response->body($body)->send_headers()->body(); 
      return TRUE; 
      break; 
     default: 
      if (Kohana::$environment == Kohana::DEVELOPMENT) 
      { 
       return Kohana_Exception::handler($e); 
      } 
      else 
      { 
       Kohana::$log->add(Log::ERROR, Kohana_Exception::text($e)); 
       $response = new Response; 
       $response->status(500); 
       $body = Request::factory('site/500')->execute()->body(); 
       echo $response->body($body)->send_headers()->body(); 
       return TRUE; 
      } 
      break; 
    } 
} 

} 
+0

我现在得到这个错误:ErrorException [Warning]:set_exception_handler()期望参数(Exception_Handler_Class :: handle_method)是一个有效的回调 – jnbdz

2

您正在使用过时的文档。 HTTP_Exception_404捆绑在3.1中,并且您试图从3.0实现解决方案。

请参阅documentation for your version of Kohana以获得有效的解决方案。

+0

让我看看它。对不起,我一直在忙于其他事情。 – jnbdz

2

所有你需要做的是将路径设置为在bootstrap.php中有不同的看法添加:

Kohana_Exception::$error_view = 'error/myErrorPage'; 

,它将分析目前被解析到,生活在错误页面的所有变量:

system/views/kohana/error.php 

即:

<h1>Oops [ <?= $code ?> ]</h1> 
<span class="message"><?= html::chars($message) ?></span> 
+0

它工作得很好,谢谢。但我想在控制器中加载一个动作。所以我有一个更好的控制...所以,如果我得到一个404错误,它会加载action_404()... – jnbdz