Codeigniter 和 PHP - 强制 404?

Posted

技术标签:

【中文标题】Codeigniter 和 PHP - 强制 404?【英文标题】:Codeigniter & PHP - forcing a 404? 【发布时间】:2010-11-17 05:32:05 【问题描述】:

如您所知,在 codeigniter 中,表单的页面:/class/function/ID,其中 class 是控制器名称,function 是控制器中的方法,ID 是传递给该方法的参数。

典型的用法是(例如对于图书网站)将图书 ID 传递给函数,然后该函数将查询数据库以查找合适的图书。我的问题是这样的:我乱七八糟地随机(在 url 字符串中)输入了数据库中不存在的 ID(正常的点和单击浏览这永远不会发生),并且由于剩余查询而出现数据库错误我尝试使用不存在的 ID 执行。

我已经编写了代码来检查在尝试使用 ID 之前是否返回了任何行,但是如果 ID 不存在,我希望用户获得 404 错误页面而不是空白页面或其他内容(因为这似乎是正确的功能)。这需要是一个真正的 404 页面(而不是简单地加载一个看起来像 404 页面的视图),以免与搜索引擎发生冲突。好的 - 所以我的问题是:在正常的程序逻辑流程中(如上所述)如何使用 codeigniter 强制出现 404 错误?谢谢。

更新:代码点火器有一个show_404('page') 函数,但我认为这不会产生真正的 HTTP 404 错误...

【问题讨论】:

【参考方案1】:

show_404() 实际上为搜索引擎发送正确的标头以将其注册为 404 页面(它发送 404 状态)。

使用 Firefox 插件检查调用 show_404() 时收到的标头。您将看到它发送了正确的 HTTP 状态代码。

勾选默认application/errors/error_404.php。第一行是:

<?php header("HTTP/1.1 404 Not Found"); ?>

该行将 HTTP 状态设置为 404。这就是搜索引擎将您的页面读取为 404 页面所需的全部内容。

【讨论】:

这是个好消息!并不是说我不相信你,但我会在接受你的回答之前尝试验证这一点。谢谢 谢谢!简短、简单、有效。 是的,它也适用于 codeigniter。制作 page_not_found 函数并从 config/routes $route['404_override'] = 'welcome/page_not_found'; function page_not_found() header("HTTP/1.1 404 Not Found"); $this-&gt;load-&gt;view('page_not_found'); 调用它 是的!这也适用于 CodeIgniter 和核心 php。【参考方案2】:
        $this->output->set_status_header('404');

生成 404 标头。

【讨论】:

【参考方案3】:

如果您想要自定义错误页面,您可以执行以下操作。在您的库中创建一个文件名 MY_Exceptions 并使用 CI_Exceptions 扩展它。然后覆盖 show_404() 函数。在此函数中,您现在可以使用 &get_instance() 函数创建 Controller 类的实例。使用此实例,您可以加载自定义 404 错误页面。

class MY_Exceptions extends CI_Exceptions 

public function __construct()
    parent::__construct();


function show_404($page = '') // error page logic

    header("HTTP/1.1 404 Not Found");
    $heading = "404 Page Not Found";
    $message = "The page you requested was not found ";
    $CI =& get_instance();
    $CI->load->view('/*Name of you custom 404 error page.*/');


【讨论】:

【参考方案4】:

只需遵循以下步骤:

第 1 步 更新你的 application/config/routes.php 文件

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

第 2 步 在控制器文件夹中创建您自己的控制器 前任。错误.php

<?php
class Error extends CI_Controller

function error_404()

    $data["heading"] = "404 Page Not Found";
    $data["message"] = "The page you requested was not found ";
        $this->load->view('error',$data);


?>

第 3 步 在视图文件夹中创建视图 前任。错误.php

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
<title><?php echo $heading;?></title>
</head>

<body>
<?php echo $message;?>
</body>
</html>

【讨论】:

【参考方案5】:

我和你有同样的问题,我在 CodeIgniter 3 中找到了一个完整的解决方案。在这里我想逐步分享如何解决它。当然,我们需要支持自定义 404 页面来满足 SEO 要求。

    为与路由中的架构不匹配的 URL 显示 404 页面 在 application/controllers 中添加新的错误控制器以支持自定义 404 页面。
class ErrorController extends CI_Controller 

    public function __construct() 
    
        parent::__construct();
     

    public function index() 
     
        $this->output->set_status_header('404');
        return $this->load->view('errors/error_404'); 
     

application/views/errors 中为 404 页面添加新的自定义视图 error_404.php
<div>
    <p>We are so sorry. The page you requested could not be found.</p> 
</div>
在 config/routes.php 中声明 404_overide
$route['404_override'] = 'ErrorController';
    为与路由中的架构匹配但指向不存在资源的 URL 显示 404 页面。 在 config/config 中设置 subclass_prefix。
$config['subclass_prefix'] = 'MY_';
application/core 中定义您的自定义异常类
class MY_Exceptions extends CI_Exceptions 

    public function __construct() 
        parent::__construct();
    

    function show_404($page = '', $log_error = TRUE) 
        $CI = &get_instance();
        $CI->output->set_status_header('404');
        $CI->load->view('errors/error_404');
        echo $CI->output->get_output();
        exit;
    


在任何地方调用 show_404()。在这里,我在 application/models 中创建了我的自定义晚餐模型类,并在那里检查查询结果。其他模型将扩展 supper 模型并在找不到资源时显示 404 页面。
abstract class MY_Model extends CI_Model


    protected $table = 'table_name';

    public function __construct()
    
        parent::__construct();
        $this->load->database();
    

    public function find($id)
    
        $result = $this->db->get_where($this->table, ['id' => $id]);
        $data = $result->row_object();

        if (!$data) 
            show_404();
        

        return $data;
    

【讨论】:

【参考方案6】:

是的 show_404() 将发送 404 但它看起来像地狱。这里提出了一些技巧,但是当您可以使用内置功能时,为什么要进行技巧呢?

Upgrade to CI 2.0,你就可以使用神奇的了:

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

然后您就可以拥有一个通用的错误控制器,而不必担心在 CI 实例中过早加载视图、库和助手 WY 以使其正常运行。

【讨论】:

【参考方案7】:

试试这个

set_status_header(404);

【讨论】:

【参考方案8】:

在您的应用程序/控制器文件夹中创建控制器。

class Error extends Controller

function error_404()

    $this->load->view('error');


然后在您的应用程序/库中通过创建应用程序/库/MY_Router.php 来扩展路由器类

class MY_Router extends CI_Router

private $error_controller = 'error';
private $error_method_404 = 'error_404';

function MY_Router()

    parent::CI_Router();


// this is just the same method as in Router.php, with show_404() replaced by $this->error_404();
function _validate_request($segments)

    // Does the requested controller exist in the root folder?
    if(file_exists(APPPATH.'controllers/'.$segments[0].EXT))
    
        return $segments;
    

    // Is the controller in a sub-folder?
    if(is_dir(APPPATH.'controllers/'.$segments[0]))
    
        // Set the directory and remove it from the segment array
        $this->set_directory($segments[0]);
        $segments = array_slice($segments, 1);
        if(count($segments) > 0)
        
            // Does the requested controller exist in the sub-folder?
            if(!file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].EXT))
            
                return $this->error_404();
            
        
        else
        
            $this->set_class($this->default_controller);
            $this->set_method('index');
            // Does the default controller exist in the sub-folder?
            if(!file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.EXT))
            
                $this->directory = '';
                return array();
            
        
        return $segments;
    
    // Can't find the requested controller...
    return $this->error_404();


function error_404()

    $segments = array();
    $segments[] = $this->error_controller;
    $segments[] = $this->error_method_404;
    return $segments;


function fetch_class()

    // if method doesn't exist in class, change
    // class to error and method to error_404
    $this->check_method();
    return $this->class;


function check_method()

    $class = $this->class;
    if (class_exists($class))
    
        if ($class == 'doc')
        
            return;
        
        if (! in_array('_remap', array_map('strtolower', get_class_methods($class)))
            && ! in_array(strtolower($this->method), array_map('strtolower', get_class_methods($class))))
        
            $this->class = $this->error_controller;
            $this->method = $this->error_method_404;
            include(APPPATH.'controllers/'.$this->fetch_directory().$this->error_controller.EXT);
        
    

如果页面不存在,会被路由到错误控制器

【讨论】:

我认为你应该相信这段代码的原作者。在这里找到maestric.com/doc/php/codeigniter_404

以上是关于Codeigniter 和 PHP - 强制 404?的主要内容,如果未能解决你的问题,请参考以下文章

使用 www 强制 HTTPS 并在 CodeIgniter 中删除 index.php .htaccess

如何在 PHP Codeigniter 中获取 40 岁以上的人员列表

PHP-CodeIgniter-新控制器

如何使用 php 和 codeigniter 隐藏检索到的数据值的重复部分

在没有 index.php 的情况下,codeigniter 重定向不起作用?

PHP CodeIgniter - MySQL 工作台