CodeIgniter中.htaccess重写规则兼容修改方案问询
问题场景
现有基于CodeIgniter开发的网站,原开发者未使用框架默认路由,自定义了.htaccess重写规则,导致路由逻辑混乱。需要保留原有.htaccess规则生效的同时,支持形如controller_name/function_name/$param1/$param2的SEO友好URL(例如已在routes.php配置的$route['download/(:any)/(:any)/(:any)'] = '/controller/download/$1/$2/$3'当前未生效),需修改.htaccess避免规则冲突。
原有.htaccess规则如下:
RewriteEngine on DirectoryIndex index.php RewriteRule ^google[0-9a-f]+.html$ - [L] RewriteRule ^(shop.html)$ index.php?mod=shop&name=$1 [L,NC] RewriteRule ^(ref.html)$ index.php?mod=ref&name=$1 [L,NC] RewriteRule ^(refs.html)$ index.php?mod=aff&s=refs&ad=$2 [L,NC] RewriteRule ^(vip-membership.html)$ index.php?mod=aff&s=top [L,NC] RewriteRule ^(dds.html)$ index.php?mod=aff&s=dds [L,NC] RewriteRule ^(news.html)$ index.php?mod=news [L,NC] RewriteRule ^(document)-(.*)-(.*).html$ index.php?mod=aff&s=document&id=$3 [L,NC] RewriteRule ^(category)-(.*)-(.*).html$ index.php?mod=aff&s=category&top=$3 [L,NC] RewriteRule ^(news)_(.*)_(.*).html$ index.php?mod=news&s=detail&name=$1&id=$2 [L,NC] RewriteRule ^(.*)_news.html$ index.php?mod=news&s=category&catname=$1&id=$2 [L,NC] RewriteRule ^(page)-(.*).html$ index.php?mod=aff&s=page&name=$2 [L,NC] RewriteRule ^([a-z0-9_-]+).html$ index.php?mod=page&name=$1 [L,NC] RewriteRule ^([a-z0-9_-]+).html$ index.php?mod=page&name=$1 [L,NC] RedirectMatch 301 ^/panel$ /index.php/panel RedirectMatch 301 ^/2017-books.html$ /dhtc-2017-books.html php_value max_input_vars 3000 php_value suhosin.get.max_vars 3000 php_value suhosin.post.max_vars 3000 php_value suhosin.request.max_vars 3000
解决方案
核心思路:原有规则均匹配.html结尾的URL,而CodeIgniter的路由URL通常不带.html后缀,因此可以在原有规则之后添加针对非.html请求的重写规则,将其交给CI的index.php处理,同时排除实际存在的文件和目录,避免静态资源(如CSS、JS、图片)被错误重写。
修改步骤
- 保留原有所有
.htaccess规则不变; - 在原有规则的
RewriteRule部分之后、RedirectMatch之前,添加以下CI路由重写规则:
# 排除实际存在的文件和目录,避免静态资源被重写 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # 处理非.html结尾的请求,交给CI的index.php RewriteRule ^(.*)$ index.php/$1 [L]
修改后的完整.htaccess
RewriteEngine on DirectoryIndex index.php RewriteRule ^google[0-9a-f]+.html$ - [L] RewriteRule ^(shop.html)$ index.php?mod=shop&name=$1 [L,NC] RewriteRule ^(ref.html)$ index.php?mod=ref&name=$1 [L,NC] RewriteRule ^(refs.html)$ index.php?mod=aff&s=refs&ad=$2 [L,NC] RewriteRule ^(vip-membership.html)$ index.php?mod=aff&s=top [L,NC] RewriteRule ^(dds.html)$ index.php?mod=aff&s=dds [L,NC] RewriteRule ^(news.html)$ index.php?mod=news [L,NC] RewriteRule ^(document)-(.*)-(.*).html$ index.php?mod=aff&s=document&id=$3 [L,NC] RewriteRule ^(category)-(.*)-(.*).html$ index.php?mod=aff&s=category&top=$3 [L,NC] RewriteRule ^(news)_(.*)_(.*).html$ index.php?mod=news&s=detail&name=$1&id=$2 [L,NC] RewriteRule ^(.*)_news.html$ index.php?mod=news&s=category&catname=$1&id=$2 [L,NC] RewriteRule ^(page)-(.*).html$ index.php?mod=aff&s=page&name=$2 [L,NC] RewriteRule ^([a-z0-9_-]+).html$ index.php?mod=page&name=$1 [L,NC] RewriteRule ^([a-z0-9_-]+).html$ index.php?mod=page&name=$1 [L,NC] # 添加CI路由支持规则 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php/$1 [L] RedirectMatch 301 ^/panel$ /index.php/panel RedirectMatch 301 ^/2017-books.html$ /dhtc-2017-books.html php_value max_input_vars 3000 php_value suhosin.get.max_vars 3000 php_value suhosin.post.max_vars 3000 php_value suhosin.request.max_vars 3000
说明
- 原有
.html结尾的URL会优先匹配原有规则,不受影响; - 非
.html结尾的URL(如download/file/123/abc)会被新规则捕获,传递给CI的index.php,此时routes.php中配置的路由规则即可正常生效; RewriteCond %{REQUEST_FILENAME} !-f和!-d确保实际存在的文件(如style.css)和目录不会被重写,保证静态资源正常访问。
内容的提问来源于stack exchange,提问作者zkanoca
相关产品推荐
相关产品推荐

