如何为Kohana v3应用程序设置自定义404页面

5
我该怎么做?我已经尝试了半个小时,这真的很恼人。你会认为这应该是一个基本且易于设置的框架。我希望可能有一种简单的方法,因为我开始认为如果这样的基本事情如此难以设置,那么我根本不应该选择这个框架。
这在我的bootstrap.php文件中应该能解决问题。
if ( ! defined('SUPPRESS_REQUEST'))
{
    /**
     * Execute the main request. A source of the URI can be passed, eg: $_SERVER['PATH_INFO'].
     * If no source is specified, the URI will be automatically detected.
     */ 
    $request = Request::instance();
    try
    {
        // Attempt to execute the response
        $request->execute();
    }
    catch (Exception $e)
    {
        if (Kohana::$environment === Kohana::DEVELOPMENT)
        {
            // Just re-throw the exception
            throw $e;
        }
        echo "ok";
        // Create a 404 response
        $request->status = 404;
        $view = View::factory('error404');
        $request->response = $view->render();
    }

    echo $request->send_headers()->response;
}

但我仍然收到 <\p>
Fatal error: Uncaught Kohana_Request_Exception [ 0 ]: Unable to find a route to match the URI: test ~ SYSPATH\classes\kohana\request.php [ 674 ] thrown in C:\Xampp\htdocs\system\classes\kohana\request.php on line 674

我自定义的404页面没有被使用。 是的,Kohana::$environment 被设置为 Kohana::PRODUCTION;

甚至连 echo "ok"; 的部分都没有执行。为什么异常没有被捕获?


1
请不要因为我说我开始觉得我不应该选择这个框架而贬低我。只是我发现这个框架对于这样一个简单的事情来说很奇怪和难以设置。现在我正在寻找一个解决方案,以便我可以继续前进,有什么建议吗? - daniels
1
很抱歉,我还没有使用过v3。在v2中,使用事件钩子系统非常容易。无论如何,这个论坛页面可能适用于您的情况,特别是最后两篇帖子:http://forum.kohanaframework.org/discussion/4777/ko3-404/p1 - Fanis Hatzidakis
我使用了全捕获方法。我设置了一个全捕获路由,在那个控制器中将状态设置为404并呈现了我的自定义404视图:D 谢谢。你应该把这个作为答案,这样我就可以接受它了。 - daniels
@daniels - 我仍在寻找一种简单的方法来做这件事。无论如何,我必须说,在我找到的复杂解决方案之间,我读到了一个参考文献,它解释了为什么万能路由方法并不总是百分之百有效,并提出了另一种更好的复杂解决方案。http://kerkness.ca/kowiki/doku.php?id=routing:404_pages_by_catching_reflection_exception - Alejandro García Iglesias
问题不在于Kohana,而在于文档。Kohana是一个很好的框架,只是缺乏高质量的文档支持。 - Gavin
3个回答

7
请将 bootstrap.php 的最后一行替换为:
/**
* Set the production status
*/
define('IN_PRODUCTION', FALSE);

/**
* Execute the main request. A source of the URI can be passed, eg: $_SERVER['PATH_INFO'].
* If no source is specified, the URI will be automatically detected.
*/
$request = Request::instance();

try
{
    $request->execute();
}
catch (Kohana_Exception404 $e)
{
    $request = Request::factory('error/404')->execute();
}
catch (Kohana_Exception403 $e)
{
    $request = Request::factory('error/403')->execute();
}
catch (ReflectionException $e)
{
    $request = Request::factory('error/404')->execute();
}
catch (Kohana_Request_Exception $e)
{
    $request = Request::factory('error/404')->execute();
}
catch (Exception $e)
{
    if ( ! IN_PRODUCTION )
    {
        throw $e;
    }

    $request = Request::factory('error/500')->execute();
}

echo $request->send_headers()->response;

创建新的控制器 "error.php":
<?php defined('SYSPATH') or die('No direct script access.');

class Controller_Error extends Controller {

    public function action_404()
    {
        $this->request->status = 404;
        $this->request->headers['HTTP/1.1'] = '404';
        $this->request->response = 'error 404';
    }

    public function action_403()
    {
        $this->request->status = 403;
        $this->request->headers['HTTP/1.1'] = '403';
        $this->request->response = 'error 403';
    }

    public function action_500()
    {
        $this->request->status = 500;
        $this->request->headers['HTTP/1.1'] = '500';
        $this->request->response = 'error 500';
    }
} // End Error

在“kohana”文件夹中创建两个文件(exception404.phpexception403.php):
<?php defined('SYSPATH') or die('No direct access');

class Kohana_Exception403 extends Kohana_Exception {

    public function __construct($message = 'error 403', array $variables = NULL, $code = 0)
    {
        parent::__construct($message, $variables, $code);
    }

} // End Kohana_Exception 403


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

class Kohana_Exception404 extends Kohana_Exception {

    public function __construct($message = 'error 404', array $variables = NULL, $code = 0)
    {
        parent::__construct($message, $variables, $code);
    }

} // End Kohana_Exception 404

现在您可以手动抛出404和403错误(无法抛出500错误;)

throw new Kohana_Exception404;
throw new Kohana_Exception403;

6
如果您和我一样,正在阅读此页面并使用Kohana 3.2(或更高版本),那么您可能需要将Kohana_Exception404替换为HTTP_Exception_404 - ereOn

6
您只需要在bootstrap.php中设置路径到不同的视图即可,添加如下代码:
Kohana_Exception::$error_view = 'error/myErrorPage';

这将解析当前正在解析的所有变量到位于错误页面中的位置:

system/views/kohana/error.php

ie:

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

这种方法有什么缺点?为什么只有很少的投票?看起来它很简洁(只有一个字符串+一个视图文件)且稳定。 - Haradzieniec

5
自从v3.1版本以来,Kohana指南包含了一个关于自定义错误页面的教程。这个教程展示了一种更加简洁的解决方案。请参考自定义错误页面教程

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接