.htaccess 中 RewriteRule 顺序错误会导致404,因Apache自上而下匹配且遇[L]终止;需将具体规则置顶、兜底规则写为RewriteRule ^(.*)$ index.php [L];同时确保AllowOverride All启用,并在PHP中正确解析REQUEST_URI或REDIRECT_URL。

Apache .htaccess 中 RewriteRule 顺序错了会直接 404
PHP URL 重写冲突导致 404,90% 情况是 RewriteRule 的匹配顺序和优先级没理清。Apache 从上到下逐条匹配,一旦某条规则命中并带有 [L] 标志,后续规则就跳过;但若规则没写好,可能把本该交给 index.php 处理的请求,误判为静态资源或非法路径,直接返回 404。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 把最具体的规则(如
/api/v1/users/123)放在最前面,泛用规则(如^(.*)$)必须垫底 - 所有兜底规则务必显式重写到
index.php,且带[L],例如:RewriteRule ^(.*)$ index.php [L]
- 禁用
RewriteEngine Off后再开,避免继承父目录配置干扰 - 用
RewriteLog(Apache 2.2)或RewriteLogLevel 3+RewriteLog(2.4 需启用mod_rewrite日志模块)看实际匹配路径
PHP 路由入口(index.php)没正确解析原始 URL 会丢参数
即使 .htaccess 把请求转到了 index.php,如果 PHP 没从 $_SERVER['REQUEST_URI'] 或 $_SERVER['REDIRECT_URL'] 里取原始路径,而是只读 $_SERVER['PHP_SELF'],就会拿到 /index.php 本身,路由完全失效,框架或自定义路由逻辑直接跳 404。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 优先用
$_SERVER['REQUEST_URI']获取完整路径(含查询参数),注意它在 CLI 或某些 FastCGI 环境下可能不可靠 - 当
REQUEST_URI为空时,回退到$_SERVER['REDIRECT_URL'](Apache mod_rewrite 注入)或$_SERVER['ORIG_PATH_INFO'] - 手动截掉 base path(如网站部署在
/subdir/),否则路由匹配永远失败 - 示例提取逻辑:
$uri = $_SERVER['REQUEST_URI'] ?? $_SERVER['REDIRECT_URL'] ?? '/';
$base = parse_url($_SERVER['SCRIPT_NAME'], PHP_URL_PATH);
$uri = str_replace($base, '', $uri);
$uri = '/' . trim($uri, '/');
AllowOverride None 让 .htaccess 完全不生效
很多 404 其实压根没进重写流程——因为 Apache 主配置中对应目录的 AllowOverride 设成了 None,.htaccess 文件被无视,请求按默认规则走,找不到对应文件就直接 404。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 检查虚拟主机或目录配置,确认有类似这样的段落:
AllowOverride All
Require all granted - 若用的是共享主机,有些面板(如 cPanel)会默认关闭
AllowOverride,需在“Apache 配置”或“.htaccess 设置”里手动开启 - 重启 Apache 后用
apachectl -t验证配置语法,再用curl -I http://yoursite.com/test看响应头是否含X-Powered-By或其他自定义头,间接判断.htaccess是否起效
Nginx 用户别套用 Apache 的 .htaccess 思路
如果你实际用的是 Nginx,却照搬 Apache 的 RewriteRule 写法、查 .htaccess 日志、调 AllowOverride,那所有排查都是错方向。Nginx 没 .htaccess,重写逻辑全在 server 或 location 块里,且匹配机制完全不同:前缀匹配 + 正则捕获,不支持 [L],用 last / break 控制流程。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- PHP 项目常用兜底写法:
location / {
try_files $uri $uri/ /index.php?$query_string;
} - 确保
fastcgi_param SCRIPT_FILENAME指向真实物理路径,否则 PHP-FPM 收不到脚本位置,也会 404 - 用
nginx -t检查配置,nginx -s reload生效,不要改完就刷新浏览器等结果











