Codeigniter 和 PHP - 强制 404?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1236768/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Codeigniter & PHP - forcing a 404?
提问by oym
In codeigniter, as you know, a page of the form: /class/function/ID, where class is the controller name, function is the method within the controller, and ID is the parameter to pass to that method.
如您所知,在 codeigniter 中,页面的形式为: /class/function/ID,其中 class 是控制器名称,function 是控制器内的方法,ID 是传递给该方法的参数。
The typical usage would be (for a book site for example) to pass the book id to the function which would then query the database for appropriate book. My problem is this: I was messing around and randomly (in the url string) typed in an ID that is not present in the database (with normal point and click browsing this would never happen) and I get database errors due to the residual queries I attempt to perform using a non-existent ID.
典型的用法是(例如对于图书站点)将图书 ID 传递给函数,然后该函数将查询数据库中的适当图书。我的问题是这样的:我乱七八糟地(在 url 字符串中)输入了一个数据库中不存在的 ID(使用正常的点击浏览,这永远不会发生),并且由于残留查询而出现数据库错误我尝试使用不存在的 ID 执行。
I have written code to check if there are any rows returned before attempting to use the ID, but if the ID is non-existent I would like the user to get a 404 error page rather than a blank page or something (since this seems like proper functionality). This would need to be a true 404 page (not simply loading a view that looks like a 404 page) so as not to screw with search engines. Okay - so my question is this: within normal program logic flow (as described above) how can I force a 404 error using codeigniter? Thanks.
我已经编写了代码来检查在尝试使用 ID 之前是否有任何返回的行,但是如果 ID 不存在,我希望用户获得 404 错误页面而不是空白页面或其他内容(因为这看起来像适当的功能)。这需要是一个真正的 404 页面(不仅仅是加载一个看起来像 404 页面的视图),以免与搜索引擎混淆。好的 - 所以我的问题是:在正常的程序逻辑流(如上所述)中,我如何使用 codeigniter 强制出现 404 错误?谢谢。
Update: code igniter has a show_404('page')function but I don't think this will generate a true HTTP 404 error...
更新:代码点火器有一个show_404('page')功能,但我认为这不会产生真正的 HTTP 404 错误......
回答by Andrew Moore
show_404()actually sends the proper headers for a search engine to register it as a 404 page (it sends 404 status).
show_404()实际上为搜索引擎发送正确的标头以将其注册为 404 页面(它发送 404 状态)。
Use a Firefox addon to check the headers received when calling show_404(). You will see it sends the proper HTTP Status Code.
使用 Firefox 插件检查调用show_404(). 您将看到它发送正确的 HTTP 状态代码。
Check the default application/errors/error_404.php. The first line is:
检查默认application/errors/error_404.php. 第一行是:
<?php header("HTTP/1.1 404 Not Found"); ?>
That line sets the HTTP Status as 404. It's all you need for the search engine to read your page as a 404 page.
该行将 HTTP 状态设置为 404。这就是搜索引擎将您的页面读取为 404 页面所需的全部内容。
回答by Jubair
$this->output->set_status_header('404');
to generate 404 headers.
生成 404 标头。
回答by sagar27
If you want a custom error page you can do the following thing.In your Libraries create a file name MY_Exceptions and extend it with CI_Exceptions.And then override the show_404() function.In this function you can now create an instance of your Controller class using &get_instance() function.And using this instance you can load your custom 404 Error page.
如果您想要自定义错误页面,您可以执行以下操作。在您的库中创建一个文件名MY_Exceptions 并使用 CI_Exceptions 扩展它。然后覆盖 show_404() 函数。在此函数中,您现在可以创建控制器类的实例使用 &get_instance() 函数。使用此实例,您可以加载自定义 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.*/');
}
回答by NBN
Only follows these steps:
只需遵循以下步骤:
Step 1Update your application/config/routes.php file
步骤 1更新您的 application/config/routes.php 文件
$route['404_override'] = 'error/error_404';
Step 2Create your own controller in controllers folder ex. error.php
第 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);
}
}
?>
Step 3Create your view in views folder ex. error.php
第 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>
回答by GianFS
try using this
尝试使用这个
set_status_header(404);
回答by Phil Sturgeon
Yes show_404() WILL send out a 404 but it looks like hell. There have been a few hacks suggested here, but why hack when you can use built in features?
是的 show_404() 会发出 404,但它看起来像地狱。这里建议了一些 hack,但是当您可以使用内置功能时,为什么还要 hack 呢?
Upgrade to CI 2.0and you'll be able to use the amazing:
升级到 CI 2.0,你将能够使用惊人的:
$route['404_override'] = 'errors/error_404';
Then you can have a general errors controller without having to worry about trying to load views, libraries and helpers WY too early in the CI instance to function properly.
然后你就可以拥有一个通用的错误控制器,而不必担心在 CI 实例中过早地尝试加载视图、库和助手 WY 以使其正常运行。
回答by Tung Nguyen
I had the same problem with you and I found a complete solution for this in CodeIgniter 3. Here I would like to share step by step how to solve it. Of course, we need to support a custom 404 page to satisfy SEO requirement.
我和你遇到了同样的问题,我在 CodeIgniter 3 中找到了一个完整的解决方案。在这里我想一步一步地分享如何解决它。当然,我们需要支持自定义 404 页面以满足 SEO 要求。
- Show 404 page for URLs which do not match the schema in routes
- Add a new Error controller in application/controllersto support a custom 404 page.
- 为与路由中的架构不匹配的 URL 显示 404 页面
- 在应用程序/控制器中添加新的错误控制器以支持自定义 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');
}
}
- Add a new custom view error_404.phpfor 404 page in application/views/errors
- 在application/views/errors 中为 404 页面添加一个新的自定义视图error_404.php
<div>
<p>We are so sorry. The page you requested could not be found.</p>
</div>
- Declare 404_overide in config/routes.php
- 在 config/routes.php 中声明 404_overide
$route['404_override'] = 'ErrorController';
- Show 404 page for URLs which match the schema in routes but point to non-existing resource.
- Set subclass_prefix in config/config.
- 为与路由中的模式匹配但指向不存在的资源的 URL 显示 404 页面。
- 在config/config 中设置 subclass_prefix 。
$config['subclass_prefix'] = 'MY_';
- Define your custom Exceptions class in application/core
- 在application/core 中定义您的自定义 Exceptions 类
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;
}
}
- Call show_404()wherever you want. Here I created my custom supper model class in application/modelsand check query results there. Other models will extends the supper model and show 404 page if they could not found a resource.
- 随时随地调用show_404()。在这里,我在应用程序/模型中创建了我的自定义超级模型类并在那里检查查询结果。其他模型会扩展超级模型并在找不到资源时显示 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;
}
}
回答by Tung Nguyen
Create controller in your application/controllers folder.
在您的应用程序/控制器文件夹中创建控制器。
class Error extends Controller
{
function error_404()
{
$this->load->view('error');
}
}
Then in your application/library extend the Router class by creating application/libraries/MY_Router.php
然后在您的应用程序/库中通过创建 application/libraries/MY_Router.php 扩展 Router 类
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);
}
}
}
}
}
If the page does not exist, it will be routed to error controller
如果页面不存在,它将被路由到错误控制器

