【问题标题】:How do I catch a HTTP_Exception_404 Error in Kohana如何在 Kohana 中捕获 HTTP_Exception_404 错误
【发布时间】:2011-11-18 12:08:54
【问题描述】:

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

此外,当我输入 URL error/404/Message 时,我会收到一条丑陋的 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

我真的看不出我哪里做错了。提前感谢您的帮助。

【问题讨论】:

    标签: php error-handling kohana http-error


    【解决方案1】:

    首先,您需要确保正在加载您的模块,方法是将其包含在 application/bootstrap.php 文件的模块部分中,如下所示

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

    您提到直接访问错误处理程序控制器的 url 会触发 404 错误,这让我认为您的模块尚未加载。

    我还建议进行更多更改。

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

    同样,由于您对控制器的命名方式,它的定位和命名方式应该有所不同。将其移至 modules/my/classes/controller/error/handler.php

    请记住,类名中的下划线表示一个新目录,如http://kohanaframework.org/3.2/guide/kohana/conventions

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

    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;
        }
    }
    
    }
    

    【讨论】:

    • 我现在收到这个错误:ErrorException [ 警告 ]: set_exception_handler() 期望参数 (Exception_Handler_Class::handle_method) 是一个有效的回调
    【解决方案2】:

    您使用的是过时的文档。 HTTP_Exception_404 捆绑在 3.1 中,您正在尝试从 3.0 实施解决方案。

    请参阅documentation for your version of Kohana 了解可行的解决方案。

    【讨论】:

    • 让我看看。抱歉,我一直在忙其他事情。
    【解决方案3】:

    您需要做的就是在您的 bootstrap.php 添加中设置不同视图的路径:

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

    这会将当前正在解析的所有变量解析到所在的错误页面:

    system/views/kohana/error.php
    

    即:

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

    【讨论】:

    • 效果很好,谢谢。但我想在控制器中加载一个动作。所以我有更好的控制...所以如果我收到 404 错误,它将加载 action_404()...
    【解决方案4】:

    经过很长时间的搜索,我终于找到了解决我的小问题的方法。

    这里是关于如何使用 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']));
    }
    

    我假设您可以在这些行之前将值“production”赋予“$_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 中的 repo 的模块:https://github.com/jnbdz/Kohana-error

    【讨论】:

    • 嗨,我正在使用 GitHub 中的模块创建自定义错误,但我仍然无法使其正常工作。你能帮帮我吗?
    • 在 Stackoverflow 上发布您的问题并在此处链接,我会尽力帮助您。
    • 谢谢,这里是link to my question
    【解决方案5】:

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

    编辑

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

    【讨论】:

    • 嗯,如果你在开发环境中,你仍然会看到Kohana提供的正常错误页面。将Kohana::DEVELOPMENT === Kohana::$environment 更改为Kohana::DEVELOPMENT !== Kohana::$environment 是否会显示自定义错误页面?
    • 不,它不会改变任何东西。
    猜你喜欢
    • 2011-06-21
    • 1970-01-01
    • 2018-12-08
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 2019-11-08
    • 2010-11-21
    • 2019-03-27
    相关资源
    最近更新 更多