CodeIgniter伪静态核心是路由匹配、Web服务器跳过文件检查、请求交由index.php处理三者缺一不可;Apache需开启mod_rewrite、AllowOverride All并配置正确.htaccess;Nginx应使用try_files而非if重写;路由正则需精确捕获,config.php中index_page须置空、uri_protocol设为REQUEST_URI,且必须加载url helper。

CodeIgniter 实现文章伪静态 URL 的核心不是“加后缀”,而是让路由匹配真实路径、Web 服务器跳过文件/目录检查、并把请求正确交给 index.php 处理——三者缺一不可,漏掉任一环都会 404。
Apache 下伪静态失效的典型表现和修复点
你改了 routes.php,加了 $route['news/(\d+)\.html'] = 'article/show/$1';,但访问 /news/123.html 直接报 404,不是代码问题,是 Apache 根本没把请求转给 CI。
- 确认
httpd.conf中LoadModule rewrite_module modules/mod_rewrite.so已取消注释 - 找到所有
AllowOverride None(常见于<directory></directory>块),改成AllowOverride All—— WAMP/XAMPP 通常有 2–3 处,别只改一处 -
.htaccess必须放在项目根目录(和index.php同级),内容用这个最稳的版本:RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php/$1 [L] - 别信网上那些带
QSA,PT或多层RewriteBase的变体,CI 3.x 默认用PATH_INFO模式,index.php/$1才能被正确解析
Nginx 下 try_files 替代 rewrite 更可靠
Nginx 不支持 .htaccess,硬套 Apache 规则会出问题。重点不是“重写”,而是“兜底”:当请求的文件或目录不存在时,交由 index.php 处理。
- 在
server块内配置location /时,必须用try_files:location / { try_files $uri $uri/ /index.php?$query_string; } - 不要用
if (!-e $request_filename) { rewrite ... }—— Nginx 官方明确不推荐在location中使用if,容易触发意外跳转或 404 - 确保
fastcgi_param SCRIPT_FILENAME指向物理路径,且fastcgi_split_path_info开启(否则PATH_INFO为空,CI 拿不到路由段) - 如果项目不在 Web 根目录(比如
/var/www/html/blog/),root要配准,且try_files中的/index.php是相对于root的,不是绝对路径
路由规则里正则捕获和参数传递的坑
伪静态 URL 的语义靠路由规则实现,但 CI 对 、 的替换很机械,稍不注意就传错参。
-
$route['article/(\d+)-(\d+)\.html'] = 'article/detail/$1/$2';这样写没问题;但如果你写成'article/detail/$2/$1',顺序就反了 - 避免在正则中用贪婪匹配,比如
news/(.*)\.html—— 若 URL 是news/2026/04/18/abc.html,$1会是整个2026/04/18/abc,控制器方法得手动explode(),不如拆成news/(\d+)/(\d+)/(\d+)/([a-z]+)\.html - 日期类路径建议用固定位数,比如
news/(\d{4})-(\d{2})-(\d{2})/(\d+)\.html,既防误匹配,也方便后续做数据库查询 - 路由规则不区分大小写,但文件系统可能区分——确保控制器类名(
Article.php)、方法名(show())和路由里写的完全一致
config.php 和 autoload.php 的配套调整
光配路由和重写不够,CI 自身行为也要对齐。
-
$config['index_page'] = '';必须设为空字符串,否则生成的site_url()仍带index.php -
$config['uri_protocol']推荐设为REQUEST_URI(CI 3.x 默认),比PATH_INFO兼容性更好,尤其在 Nginx + PHP-FPM 组合下 -
urlhelper 必须加载($autoload['helper'] = ['url'];),否则site_url('article/show/123')无法生成带伪静态后缀的链接 - 生成 HTML 链接时,别手写
<a href="/news/123.html"></a>,用site_url('article/show/123')并配合路由规则,才能保证开发/生产环境 URL 一致
真正难的不是写那几行重写规则,而是理解请求从浏览器发出后,如何经过 Web 服务器、PHP、CI 框架三层拦截与转发——每层都可能吃掉路径、丢掉参数、或拒绝处理。调试时优先看 Apache 的 error_log 或 Nginx 的 error.log,里面往往直接告诉你哪一步没走通。











