CodeIgniter 2.1 的 show_404() 和 404_override 问题

Posted

技术标签:

【中文标题】CodeIgniter 2.1 的 show_404() 和 404_override 问题【英文标题】:CodeIgniter 2.1 issue with show_404() and 404_override 【发布时间】:2012-01-15 08:39:36 【问题描述】:

我使用 CodeIgniter 已经有一段时间了,目前我正在为一个想要自定义 404 页面的客户做一个项目。一切都很好,404_override 效果很好。

当访问者试图访问不存在的文章时,我的问题出现了/p>

我已经看到一些针对旧版本的修复,但我无法让它在 2.1 中工作。因此,如果有人能帮助我解决这个问题,我将不胜感激。

【问题讨论】:

【参考方案1】:

重定向是最干净的;加载视图也可以。

这里的问题是 show_404() 通常在您的控制器已经加载之后调用(毕竟必须告诉它显示 404)。 CI 不喜欢此时加载第二个控制器,这是主要障碍。

您最好的选择可能是扩展 Exceptions 类中的 show_404() 函数以重定向到您的 404 路由。如果没有重定向,您将无法在调用 404 之前显示视图或您知道具有所需的所有“额外数据”的东西(或者我猜您也可以在 Exceptions 类中加载它)。在某些动态视图中,它会变得非常复杂。

您显然想要比仅仅编辑错误文件夹中的 404 模板更高级的东西。我在尝试从该文件访问 get_instance() 时遇到问题,因为有时它是在构造控制器之前加载的。因此,如果您尝试这样做,请小心;)

更新:这是一个扩展 show_404() 函数以加载视图的工作示例

<?php
// application/core/MY_Exceptions.php
class MY_Exceptions extends CI_Exceptions 

    public function show_404()
    
        $CI =& get_instance();
        $CI->load->view('my_notfound_view');
        echo $CI->output->get_output();
        exit;
    

【讨论】:

感谢您的回复。首先,我听说重定向是个坏主意,因为它不会在正确的页面上显示 404(相反,所有 404 都将显示为在 example.com/404 上发生),这应该是个坏主意。正如您所写,我真正想要的是能够在 404 错误中加载视图,以包括我的导航、页眉和页脚。如果我可以使用视图,那么编辑 404 模板将是一个选项。我尝试了 get_instance 没有任何运气,找到了一篇关于它的博文,但没有帮助(它是从 2008 年开始的)。 非常感谢。有了这个小代码,sn-p 帮了我很多忙。我什至尝试自己加载我制作的控制器以显示我的 404,但似乎 $CI->load-> 不支持控制器。 (我用于 404_override 的那个)。但这让我很开心:) 也许重构您的 404_override 控制器以简单地调用 show_404(),并让 show_404() 函数加载您需要的所有数据。保持干燥的人... ;) 你会怎么做呢?现在我的 404_override 转到“frontpage/404”,它只调用与上述代码相同的视图。我看不出写 $this->view('404') 和 show_404(); 的不同之处。除了它更小。我仍然需要制作一个完整的控制器才能做到这一点。或者你知道我不知道的事情:) 我在 CI 论坛上读到的东西......这不应该也包括 $CI-&gt;output-&gt;set_status_header('404'); 用于干净的 SEO 目的吗?【参考方案2】:

我解决问题的快速方法是在我正在处理的项目的自动加载的帮助文件中创建一个函数。这个助手只是重定向到自定义 404 页面。所以我只打电话给show_my_404() 而不是show_404()

function show_my_404()   
    //Using 'location' not work well on some windows systems
    redirect('controller/page404', 'location');  

【讨论】:

【参考方案3】:
  function show_404($page = '', $log_error = TRUE)

    if ($log_error)
    
        log_message('error', '404 Page Not Found --> '.$page);
    
    redirect(base_url().index_page().'/controller/error_page');
           //OR
           //redirect('SOME URL');

    exit;

【讨论】:

【参考方案4】:

我一直在寻找同样的东西,但找到了相当长的解决方案,比如创建自己的错误控制器和异常类,或者只是重定向到 404 页面(这在语义上并不好)。

所以我对 CI 如何在内部调用“404_override”路由进行了一些研究。这是我想出的解决方案:

// Override show_404 method
function show_404()
    // Load Router and Core classes.
    $RTR =& load_class('Router', 'core');

    // Get class and method for 404 from routes.php
    $x = explode('/', $RTR->routes['404_override']);
    $class = $x[0];
    $method = (isset($x[1]) ? $x[1] : 'index');

    // Get current class and method for callback
    $callback_class = $RTR->fetch_class();
    $callback_method = $RTR->fetch_method();
    // Can also log here, using callback class and method.

    // Create object for callback
    $CI = new $callback_class;
    call_user_func_array(array(&$CI, $method), array_slice(array($class,$method), 2));
 // End!

system/core/CodeIgniter.php文件中添加这个函数。 这将覆盖 show_404 函数。您可以从控制器调用它,它会调用 routes.php 文件中给出的“404_override”路由。

【讨论】:

请不要核心破解 :)

以上是关于CodeIgniter 2.1 的 show_404() 和 404_override 问题的主要内容,如果未能解决你的问题,请参考以下文章

CodeIgniter2的Doctrine2 CLI

如何在CodeIgniter中编写更好的模型

CodeIgniter AJAX

阻止公共访问CodeIgniter中的CRON作业脚本

使用CodeIgniter删除并设置Cookies

在 codeigniter 2.1 中分析缓存使用情况