CodeIgniter 路由和 404 自定义错误
Posted
技术标签:
【中文标题】CodeIgniter 路由和 404 自定义错误【英文标题】:CodeIgniter Routing and 404 Custom Errors 【发布时间】:2016-08-04 15:53:29 【问题描述】:我使用 CodeIgniter。
我使用 routes.php 文件根据 url 的结构将某些 url 路由到不同的文件。一切正常。
然而,几个月前,我想我会添加一个自定义 404 页面。我做到了,一切似乎都很好。
但是,我刚刚意识到我网站上的每个页面(主页除外)都会给出 404 错误的服务器响应,但会向人类用户显示正确的页面作为自定义页面!
我不知道这是怎么回事,但这显然是一场噩梦,因为我现在没有从所有搜索引擎列表中编入索引!!!域名是http://citylightstours.com
ROUTES.PHP
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
| -------------------------------------------------------------------------
| URI ROUTING
| -------------------------------------------------------------------------
| This file lets you re-map URI requests to specific controller functions.
|
| Typically there is a one-to-one relationship between a URL string
| and its corresponding controller class/method. The segments in a
| URL normally follow this pattern:
|
| example.com/class/method/id/
|
| In some instances, however, you may want to remap this relationship
| so that a different class/function is called than the one
| corresponding to the URL.
|
| Please see the user guide for complete details:
|
| http://codeigniter.com/user_guide/general/routing.html
|
| -------------------------------------------------------------------------
| RESERVED ROUTES
| -------------------------------------------------------------------------
|
| There area two reserved routes:
|
| $route['default_controller'] = 'welcome';
|
| This route indicates which controller class should be loaded if the
| URI contains no data. In the above example, the "welcome" class
| would be loaded.
|
| $route['404_override'] = 'errors/page_missing';
|
| This route will tell the Router what URI segments to use if those provided
| in the URL cannot be matched to a valid route.
|
*/
$route['default_controller'] = "content";
$route['en/(:num)/(:any)'] = "content/en/$1";
$route['de/(:num)/(:any)'] = "content/de/$1";
$route['es/(:num)/(:any)'] = "content/es/$1";
$route['it/(:num)/(:any)'] = "content/it/$1";
$route['ar/(:num)/(:any)'] = "content/ar/$1";
$route['404_override'] = '';
/* End of file routes.php */
/* Location: ./application/config/routes.php */
.HTACCESS 文件:
<IfModule mod_rewrite.c>
# Development
RewriteEngine On
RewriteBase /
RewriteCond %REQUEST_FILENAME !-f
RewriteCond %REQUEST_FILENAME !-d
RewriteCond $1 !^(index\.php|images|scripts|styles|vendor|robots\.txt)
RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>
DirectoryIndex index.php
RewriteEngine on
RewriteCond $1 !^(index\.php|images|css|js|robots\.txt|favicon\.ico)
RewriteCond %REQUEST_FILENAME !-f
RewriteCond %REQUEST_FILENAME !-d
RewriteRule ^(.*)$ ./index.php/$1 [L,QSA]
# ----------------------------------------------------------------------
# Better website experience for IE users
# ----------------------------------------------------------------------
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>
BrowserMatch MSIE ie
Header set X-UA-Compatible "IE=Edge,chrome=1" env=ie
</IfModule>
</IfModule>
<IfModule mod_headers.c>
Header append Vary User-Agent
</IfModule>
# ----------------------------------------------------------------------
# Webfont access
# ----------------------------------------------------------------------
<FilesMatch "\.(ttf|otf|eot|woff|font.css)$">
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
</FilesMatch>
# ----------------------------------------------------------------------
# Proper MIME type for all files
# ----------------------------------------------------------------------
# audio
AddType audio/ogg oga ogg
# video
AddType video/ogg .ogv
AddType video/mp4 .mp4
AddType video/webm .webm
# Proper svg serving. Required for svg webfonts on iPad
# twitter.com/FontSquirrel/status/14855840545
AddType image/svg+xml svg svgz
AddEncoding gzip svgz
# webfonts
AddType application/vnd.ms-fontobject eot
AddType font/truetype ttf
AddType font/opentype otf
AddType application/x-font-woff woff
# assorted types
AddType image/x-icon ico
AddType image/webp webp
AddType text/cache-manifest appcache manifest
AddType text/x-component htc
AddType application/x-chrome-extension crx
AddType application/x-xpinstall xpi
AddType application/octet-stream safariextz
# ----------------------------------------------------------------------
# gzip compression
# ----------------------------------------------------------------------
<IfModule mod_deflate.c>
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>
SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X15|~15|-15)$ ^((gzip|deflate)\s,?\s(gzip|deflate)?|X4,13|~4,13|-4,13)$ HAVE_Accept-Encoding
RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
</IfModule>
</IfModule>
<FilesMatch "^(?!.*\.ogg$|.*\.ogv$|.*\.mp4$).+" >
# html, txt, css, js, json, xml, htc:
<IfModule filter_module>
FilterDeclare COMPRESS
FilterProvider COMPRESS DEFLATE resp=Content-Type /text/(html|css|javascript|plain|x(ml|-component))/
FilterProvider COMPRESS DEFLATE resp=Content-Type /application/(javascript|json|xml|x-javascript)/
FilterChain COMPRESS
FilterProtocol COMPRESS change=yes;byteranges=no
</IfModule>
</FilesMatch>
# webfonts and svg:
<FilesMatch "\.(ttf|otf|eot|svg)$" >
SetOutputFilter DEFLATE
</FilesMatch>
</IfModule>
# ----------------------------------------------------------------------
# Expires headers (for better cache control)
# ----------------------------------------------------------------------
<IfModule mod_expires.c>
ExpiresActive on
# Perhaps better to whitelist expires rules? Perhaps.
ExpiresDefault "access plus 1 month"
# cache.appcache needs re-requests in FF 3.6 (thx Remy ~Introducing HTML5)
ExpiresByType text/cache-manifest "access plus 0 seconds"
# your document html
ExpiresByType text/html "access plus 0 seconds"
# data
ExpiresByType text/xml "access plus 0 seconds"
ExpiresByType application/xml "access plus 0 seconds"
ExpiresByType application/json "access plus 0 seconds"
# rss feed
ExpiresByType application/rss+xml "access plus 1 hour"
# favicon (cannot be renamed)
ExpiresByType image/x-icon "access plus 1 week"
# media: images, video, audio
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType video/ogg "access plus 1 month"
ExpiresByType audio/ogg "access plus 1 month"
ExpiresByType video/mp4 "access plus 1 month"
ExpiresByType video/webm "access plus 1 month"
# htc files (css3pie)
ExpiresByType text/x-component "access plus 1 month"
# webfonts
ExpiresByType font/truetype "access plus 1 month"
ExpiresByType font/opentype "access plus 1 month"
ExpiresByType application/x-font-woff "access plus 1 month"
ExpiresByType image/svg+xml "access plus 1 month"
ExpiresByType application/vnd.ms-fontobject "access plus 1 month"
# css and javascript
ExpiresByType text/css "access plus 2 months"
ExpiresByType application/javascript "access plus 2 months"
ExpiresByType text/javascript "access plus 2 months"
<IfModule mod_headers.c>
Header append Cache-Control "public"
</IfModule>
</IfModule>
# ----------------------------------------------------------------------
# ETag removal
# ----------------------------------------------------------------------
FileETag None
# ----------------------------------------------------------------------
# Stop screen flicker in IE on CSS rollovers
# ----------------------------------------------------------------------
# The following directives stop screen flicker in IE on CSS rollovers - in
# combination with the "ExpiresByType" rules for images (see above). If
# needed, un-comment the following rules.
# BrowserMatch "MSIE" brokenvary=1
# BrowserMatch "Mozilla/4.[0-9]2" brokenvary=1
# BrowserMatch "Opera" !brokenvary
# SetEnvIf brokenvary 1 force-no-vary
RewriteEngine On
RewriteCond %HTTP_HOST !^citylightstours\.com$ [NC]
RewriteRule ^(.*)$ http://citylightstours.com/$1 [R=301,L]
RewriteCond %HTTP_USER_AGENT libwww-perl.*
RewriteRule .* ? [F,L]
我有一个 MY_Router.php 文件来处理客户 404 页面,想知道这是否错误地设置了 404 http 状态??
MY_Router.php 文件:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class MY_Router extends CI_Router
var $error_controller = 'error';
var $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()
$this->directory = "";
$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()
$ignore_remap = true;
$class = $this->class;
if (class_exists($class))
// methods for this class
$class_methods = array_map('strtolower', get_class_methods($class));
// ignore controllers using _remap()
if($ignore_remap && in_array('_remap', $class_methods))
return;
if (! in_array(strtolower($this->method), $class_methods))
$this->directory = "";
$this->class = $this->error_controller;
$this->method = $this->error_method_404;
include(APPPATH.'controllers/'.$this->fetch_directory().$this->error_controller.EXT);
function show_404()
include(APPPATH.'controllers/'.$this->fetch_directory().$this->error_controller.EXT);
call_user_func(array($this->error_controller, $this->error_method_404));
/* End of file MY_Router.php */
/* Location: ./system/application/libraries/MY_Router.php */
有人可以帮忙吗??
谢谢
【问题讨论】:
我认为它正在查找页面并返回它,但将服务器响应代码设置为 404。它将在 CodeIgniter 中设置在哪里???? 【参考方案1】:您的路线需要修复:-
$route['en/(:num)/(:any)'] = "content/en/$1";
$route['de/(:num)/(:any)'] = "content/de/$1";
$route['es/(:num)/(:any)'] = "content/es/$1";
$route['it/(:num)/(:any)'] = "content/it/$1";
$route['ar/(:num)/(:any)'] = "content/ar/$1";
请阅读:-
http://www.codeigniter.com/userguide2/general/routing.html
根据您的路由,每种语言都有一个控制器。例如(enController、deController、esController 等...),我假设你没有,你只有一个内容控制器。
您正在寻找的回复可以在这里找到:-
https://github.com/bcit-ci/CodeIgniter/wiki/URI-Language-Identifier
【讨论】:
您好,codenathan,感谢您抽出宝贵时间回复。我读了那篇文章,看不出我的路线有什么问题——它链接到内容类和语言方法。我不认为它指定了不同的内容控制器 - 只是一个具有不同方法的控制器......?无论如何,我删除了对路线语言方面的引用,但我仍然得到 404 服务器响应,并且正确的页面显示为人类自定义页面....有什么想法吗?? 抱歉,我看错了,您能发布您的内容控制器代码吗? 嗨,codenathan,我可以,但我认为这与我的内容控制器无关。一切正常,因为它正确运行并从数据库中获取正确的页面数据并正确显示它。问题是它以 404 而不是 200 的 http 状态显示它。我有一个自定义错误页面,并认为它可能与我为了执行此自定义 404 而拥有的 MY_Router.php 文件有关。我会发布MYRouter 代码...以上是关于CodeIgniter 路由和 404 自定义错误的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Codeigniter 在自定义 404 页面中重定向 404 错误?
自定义 404 未在实时服务器上的 Codeigniter 中显示