apache的.htaccess重写规则需启用mod_rewrite和allowoverride all,以rewriteengine on开头,用rewritecond跳过静态文件,rewriterule配合[qsa,l]将请求路由至index.php,并确保路径匹配uri、正确解析参数。

Apache 的 .htaccess 重写规则怎么写才不 404
PHP 本身不处理 URL 重写,真正干活的是 Web 服务器(比如 Apache)。.htaccess 是 Apache 的配置文件,必须放在网站根目录且 AllowOverride All 已启用,否则规则完全不生效。
常见错误现象:404 Not Found、页面能访问但 $_GET 拿不到参数、重写后 CSS/JS 路径全错。
- 确保 Apache 启用了
mod_rewrite:运行a2enmod rewrite并重启服务 -
.htaccess文件名必须全小写,不能是HTACCESS或带扩展名 - 开头加
RewriteEngine On,否则所有RewriteRule都被忽略 - 路径匹配基于请求 URI(不含域名和查询参数),
/article/123中的/article/123才是匹配目标 - 静态资源(
.css、.js、.png)建议跳过重写,避免 404:RewriteCond %{REQUEST_FILENAME} !-f<br>RewriteCond %{REQUEST_FILENAME} !-d<br>RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
$_GET 拿不到重写后的参数?检查 [QSA] 和路由解析逻辑
重写只是把原始请求“伪装”成另一个 URL,PHP 不会自动解析路径段为变量。你得自己拆解 $_SERVER['REQUEST_URI'] 或从重写传入的参数里取值。
比如 RewriteRule ^post/([0-9]+)$ index.php?id=$1 [QSA,L] 这条规则,[QSA](Query String Append)的作用是保留原有查询参数,比如访问 /post/123?ref=home,最终 PHP 能拿到 $_GET['id'] = '123' 和 $_GET['ref'] = 'home'。
立即学习“PHP免费学习笔记(深入)”;
- 漏掉
[QSA]会导致原有?key=val丢失 -
[L]表示“最后一条”,不加它可能被后续规则覆盖 - 别依赖
$_GET直接对应路径段;更健壮的做法是统一入口(如index.php),在 PHP 里用parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)拆分路径 - 如果用了
PATH_INFO方式(如index.php/article/123),要确认cgi.fix_pathinfo=1(PHP 配置),否则$_SERVER['PATH_INFO']为空
Nginx 用户别硬套 .htaccess——改 location 块才对
PHP 代码本身没变,但 Web 服务器换 Nginx 后,.htaccess 完全无效。Nginx 不读这个文件,所有重写逻辑必须写进站点配置的 server 或 location 块里。
典型等效写法:
Apache 的 RewriteRule ^article/([0-9]+)$ /index.php?id=$1 [QSA,L]
对应 Nginx 的:
location ~ ^/article/(\d+)$ {<br> try_files $uri $uri/ /index.php?id=$1;<br>}
- Nginx 的
try_files是核心,它按顺序检查文件是否存在,最后回退到 PHP 入口 - 正则捕获组用
$1、$2引用,不是$1和\1 - 没有
[QSA]概念,原查询参数默认透传,但需确保fastcgi_param QUERY_STRING $query_string;在 fastcgi 配置中存在 - 改完 Nginx 配置必须执行
nginx -t && nginx -s reload,否则不生效
SEO 友好链接的两个隐藏雷区
看似只是改个 URL,实际影响搜索引擎抓取和用户点击率。最容易被忽略的是响应状态码和重复内容。
- 旧链接(如
/index.php?id=123)必须返回301 Moved Permanently重定向到新链接(/article/123),否则搜索引擎当两个独立页面,分散权重 - 同一内容不能同时通过多个 URL 访问(比如
/article/123和/article/123/都返回 200),要用RewriteRule ^article/([0-9]+)/$ /article/$1 [R=301,L]统一结尾斜杠 - 动态生成的 URL(如分页、筛选)容易产出海量低质页面,建议用
rel="canonical"指定规范地址,或直接noindex - 重写后务必测试爬虫视角:用
curl -I https://yoursite.com/article/123看返回状态码是否为 200,且无意外跳转
URL 重写的本质是让服务器和人眼看到的路径一致,但背后 PHP 处理逻辑不变。最麻烦的永远不是写那几行规则,而是验证每种访问方式(带参、不带参、带斜杠、不带斜杠、静态资源)都走对了路。











