必须启用mod_rewrite并配置allowoverride all,.htaccess需放对目录(ci3在根目录、ci4在public/),且$config['index_page'] = ''与nginx的try_files或apache重写规则协同生效。

Apache环境下.htaccess必须启用mod_rewrite
CodeIgniter的友好URL依赖Apache的重写模块,如果访问example.com/index.php/welcome能工作,但去掉index.php就404,大概率是mod_rewrite没启用或AllowOverride被禁用。
检查方式:phpinfo()里搜索Loaded Modules,确认含rewrite_module;再看Apache配置中对应站点的<directory></directory>块是否设置了AllowOverride All(不是None)。
常见错误操作:
- 只放
.htaccess文件,但AllowOverride仍是None→ 重写规则完全不生效 - 启用了
mod_rewrite,但未重启Apache(sudo systemctl restart apache2或httpd) - 把
.htaccess放在子目录而非项目根目录(即与index.php同级)
CodeIgniter 3和4的.htaccess写法差异很大
CI3默认使用index.php作为入口,CI4则默认用public/index.php,重写目标路径完全不同,不能混用。
CI3标准写法(放在项目根目录):
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
CI4标准写法(放在public/目录下):
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
关键区别:
- CI3的
index.php在根目录,规则需匹配整个URI路径 - CI4的
index.php在public/内,.htaccess也必须放在这里,否则$_SERVER['SCRIPT_NAME']解析错位,路由全崩 - CI4若用
index.php重命名或移出public/,重写规则必须同步调整路径,否则404或500
$config['index_page']设为空字符串后仍跳转index.php
这是典型配置与重写未协同的结果。仅改application/config/config.php里的$config['index_page'] = '';不够,必须同时满足三个条件:
-
.htaccess已正确部署且生效(见前两节) - Apache能读取该
.htaccess(权限、AllowOverride、模块启用) - 浏览器缓存了302跳转(旧地址带
index.php被Chrome等缓存重定向)→ 强制清空浏览器缓存或用隐身窗口测试
另外,CI4还要确认app/Config/App.php中$indexPage = '';已设置,且$uriProtocol未强制为QUERY_STRING等异常值。
Nginx用户别硬套.htaccess,直接配location块
Nginx不支持.htaccess,试图把Apache规则丢进Nginx配置会直接报错或路由失效。
CI3推荐Nginx配置片段(server块内):
location / {
try_files $uri $uri/ /index.php?$query_string;
}
CI4对应写法(root指向public/):
location / {
try_files $uri $uri/ /index.php?$query_string;
}
注意点:
- CI4的
root指令必须指向public/目录,不是项目根目录 -
try_files末尾的/index.php?$query_string不能漏掉$query_string,否则GET参数丢失 - 部分Nginx版本需显式加
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;防路径解析错误
重写本身不难,难的是Apache/Nginx配置、框架版本、入口路径、服务器权限四者咬合——漏掉任意一环,URL就卡在index.php里出不来。










