【问题标题】:CodeIgniter 404 pageCodeIgniter 404 页面
【发布时间】:2012-06-02 07:00:17
【问题描述】:

当我在我的网站上输入一个不存在的 url 时,它会将我带到 routes.php 中指定的 404 页面:

$route['404_override'] = 'page/not_found';

所以页面的设计就是我在“page”目录下的视图not_found.php中做的。

但是,如果我使用此功能手动强制执行 404:

show_404();

它带我进入没有样式的默认 CodeIgniter 404 页面:

404 Page Not Found

The page you requested was not found.

如何让它转到我在路由文件中指定的同一个 404 页面?

【问题讨论】:

标签: php codeigniter


【解决方案1】:

这里的所有答案似乎都已经过时(至少从第 2 版开始)或过于矫枉过正。这是一个更简单且易于管理的方法,只涉及两个步骤:

  1. application/config/routes.php 中修改字段 404_override 以指向某个控制器:

    // Specify some controller of your choosing
    $route['404_override'] = 'MyCustom404Ctrl';
    
  2. 在您的routes.php 中指定的控制器内,实现index() 方法,以便加载您的自定义错误404 视图。您可能还想设置一些标头,以便浏览器知道您正在返回 404 错误:

    // Inside application/controllers/MyCustom404Ctrl.php
    class MyCustom404Ctrl extends CI_Controller  {
        public function __construct() {
            parent::__construct();
        }
    
        public function index(){
            $this->output->set_status_header('404');
    
            // Make sure you actually have some view file named 404.php
            $this->load->view('404');
        }
    }
    

就像提到的代码内注释一样,请确保在 application/views/404.php 中有一个视图文件,您实际上拥有自定义 404 页面。

附带说明一下,此页面中的一些答案建议您修改 /system 中的内容,这是一个坏主意,因为当您更新 CodeIgniter 版本时,您将覆盖您的更改。我建议的解决方案不会与核心文件混淆,这使您的应用程序更加便携和可维护,并且具有抗更新性。

【讨论】:

    【解决方案2】:

    使用_remap() 函数。这允许你做一些非常强大的东西,除了通常内置的 404 错误 - 例如

    • 不同的 404 消息取决于用户是否登录!
    • 额外记录 404 错误 - 您现在可以查看 404 的推荐人是什么,从而帮助追踪错误。这包括查看它是否是机器人(例如 Google 机器人) - 或者它是否是登录用户,哪个用户导致了 404(因此您可以联系他们以获取更多信息 - 或者如果他们试图猜测管理员路线,则禁止他们什么的)
    • 忽略某些 404 错误(例如 iPhone 用户的 precomposed.png 错误)。
    • 如果您有特定需求,允许某些控制器以不同方式处理自己的 404 错误(例如,允许博客控制器重新路由到最新博客)

    让你所有的控制器都扩展MY_Controller:

    class MY_Controller extends CI_Controller
    {
        // Remap the 404 error functions
        public function _remap($method, $params = array())
        {
            // Check if the requested route exists
            if (method_exists($this, $method))
            {
                // Method exists - so just continue as normal
                return call_user_func_array(array($this, $method), $params);
            }
    
            //*** If you reach here you have a 404 error - do whatever you want! ***//
    
            // Set status header to a 404 for SEO
            $this->output->set_status_header('404');
    
    
            // ignore 404 errors for -precomposed.png errors to save my logs and
            // stop baby jesus crying
            if ( ! (strpos($_SERVER['REQUEST_URI'], '-precomposed.png')))
            {
                // This custom 404 log error records as much information as possible
                // about the 404. This gives us alot of information to help fix it in
                // the future. You can change this as required for your needs   
                log_message('error', '404:  ***METHOD: '.var_export($method, TRUE).'  ***PARAMS: '.var_export($params, TRUE).'  ***SERVER: '.var_export($_SERVER, TRUE).' ***SESSION: '.var_export($this->session->all_userdata(), TRUE));
            }
    
            // Check if user is logged in or not
            if ($this->ion_auth->logged_in())
            {
                // Show 404 page for logged in users
                $this->load->view('404_logged_in');
            }
            else
            {
                // Show 404 page for people not logged in
                $this->load->view('404_normal');
            }
       }
    

    然后在routes.php 中将您的 404 设置为您的主控制器,设置为 不存在 的功能 - 即

    $route['404']             = "welcome/my_404";
    $route['404_override']    = 'welcome/my_404';
    

    但是NO欢迎使用my_404() 函数 - 这意味着您的所有 404 都将通过 _remap 函数 - 因此您实现 DRY 并将所有 404 逻辑集中在一个位置。

    在逻辑中使用 show_404() 还是仅使用 redirect('my_404') 取决于您。如果您使用show_404() - 然后只需修改 Exceptions 类以重定向

    class MY_Exceptions extends CI_Exceptions
    {
        function show_404($page = '', $log_error = TRUE)
        {
             redirect('my_404');
        }
    }
    

    【讨论】:

    • @monkeymatrix - 这能回答你的问题吗?
    • 感谢您的回复。我现在只是在赶上回复,看看是否有适合赏金的账单:)
    • 这只在方法缺失时有效,在类缺失时无效。
    • @pbarney 不 - 你错了。因为我们还重载了 show_404 异常,该异常在类不存在时触发 - 所以它解决了这个问题
    【解决方案3】:

    要更改 show_404 的行为,您需要从 CI 核心 (system/Core/Common.php) 修改文件,这对于功能更新不太实用。

    除此之外,您可以:

    1. Redirect 用户到 $route['404_override'] 中指定的同一地点 controller/method

    2. 您可以创建一个自定义库来处理自定义 404 并像 $libInstance->show_404(); 一样使用它

      public function show_404() {
          set_status_header(404);
      
          return "404 - not found";
      }
      
    3. 或者使用视图:

      public function show_404($template) {
          set_status_header(404);
      
          if (ob_get_level() > $this->ob_level + 1)
          {
              ob_end_flush();
          }
          ob_start();
      
          include(APPPATH.'views/'.$template.'.php');
          $buffer = ob_get_contents();
          ob_end_clean();
      
          return $buffer;
      }
      

    【讨论】:

    • 虽然我很欣赏 TheShiftExchange 下面的回答非常有用,但我喜欢这个提供替代实现的替代实现,这些实现更有可能满足下一个寻找问题解决方案的用户。我认为总的来说,我建议按照下面的描述扩展控制器类,然后用这个答案中描述的视图声明一个 cutom 404 函数。非常感谢大家。
    【解决方案4】:

    如果您尝试了 user_guide,您会看到显示如下:

    show_404('page' [, 'log_error']) 函数需要字符串 传递给它作为未找到页面的文件路径。笔记 如果控制器是,CodeIgniter 会自动显示 404 消息 没找到。

    因此您需要将控制器名称作为第一个参数传递。第二个是启用或禁用日志记录。

    【讨论】:

      【解决方案5】:

      CodeIgniter 带有一个默认的 404 错误页面但是通过使用 codeigniter 的路由选项,您可以轻松地向您的用户显示您的自定义 404 错误页面。

      要做到这一点,只需转到您的 codeigniter 项目的路由文件并在下面的行中输入

      $route['404_override'] = 'error_404';
      

      这里的 error_404 是一个控制器文件,用于在您的 codeigniter 项目中显示自定义 404 错误页面或任何其他类型的错误页面。

      创建 error_404 文件并将此代码复制到此文件中

      class Error_404 extends CI_controller
      {
      
        public function index()
        {
          $this->output->set_status_header('404');
                  // Make sure you actually have some view file named 404.php
                  $this->load->view('Error_page');
        }
      }
      

      在您的 CodeIgniter 视图文件夹中创建 Error_page 视图文件,就是这样,输入任何错误的 url,现在您可以看到您的自定义 404 错误页面。

      如果您有任何疑问,可以按照此tutorial 进行操作,其中包含在 codeigniter 中创建自定义 404 错误页面的分步教程

      【讨论】:

        【解决方案6】:

        application/errors/error_404.php 文件更改为您要显示的页面。这就是show_404() 显示的文件...

        *show_404('page' [, 'log_error'])
        

        此函数将使用以下错误模板显示提供给它的 404 错误消息:

        application/errors/error_404.php
        

        该函数期望传递给它的字符串是未找到页面的文件路径。请注意,如果找不到控制器,CodeIgniter 会自动显示 404 消息。

        CodeIgniter 会自动记录任何show_404() 调用。将可选的第二个参数设置为FALSE 将跳过日志记录。*

        【讨论】:

          【解决方案7】:

          您需要在 application/config/routes.php 中设置以下代码

          $route['404_override'] = 'page/not_found';
          

          在应用程序/控制器中创建一个名为“page.php”的控制器后

          <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
          
          class page extends CI_Controller {
          
              public function __construct(){
                  parent::__construct();
              }
          
              public function not_found() {   
                  $this->load->view('not_found');
              }
          }
          

          然后您可以在名为“not_found.php”的应用程序/视图中为 404 错误页面创建自己的设计

          <html>
           <body>
            <section>
             <div>
              <div align="center" style="margin-top:50px; margin-bottom:50px;">
               <img src="<?php echo base_url();?>images/404.jpg" /> // will be your image path.
              </div>
             </div>
            </section>
           </body>
          </html>
          

          或者

          <html>
           <body>
            <section>
             <div>
              <div align="center" style="margin:0px auto;">
               <h1>OOPS!</h1>
               <h3>Sorry, an error has occured, Requested page not found!</h3>
               <h5 align="center"><a href="<?php echo base_url(); ?>">Back to Home</a></h5>
              </div>
             </div>
            </section>
           </body>
          </html>
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-07-28
            • 2020-07-14
            • 2019-12-02
            • 1970-01-01
            • 1970-01-01
            • 2017-07-02
            相关资源
            最近更新 更多