
当使用 rewriterule 实现友好 url(如 post/122)时,原有查询参数(如 ?page=2&sort=date)会丢失;添加 [qsa](query string append)标志可自动将原始 get 参数追加到重写后的目标 url 中,确保 $_get 数据完整可用。
在构建现代 PHP 网站时,友好的 URL(如 post/122 或 post/122?page=3&filter=hot)不仅能提升用户体验与 SEO 表现,还要求后端能正确解析所有传入参数。然而,许多开发者在配置 .htaccess 的 RewriteRule 时会遇到一个常见问题:重写后原始 GET 参数消失,$_GET 数组为空或不完整。
例如,你希望支持以下两种访问形式:
- https://yoursite.com/post/122 → 解析为 index.php?id=122
- https://yoursite.com/post/122?page=2&sort=updated → 仍需正确解析 id=122 且保留 page=2 和 sort=updated
但若 .htaccess 写成这样:
RewriteRule post/(.*)/ index.php?id=$1 RewriteRule post/(.*) index.php?id=$1
Apache 默认会丢弃原始查询字符串(即 ?page=2&sort=updated 部分),导致 $_GET 中只有 ['id' => '122'],而 page 和 sort 完全不可见。
✅ 正确解法:添加 [QSA](Query String Append)标志:
Options +FollowSymLinks RewriteEngine On RewriteRule ^post/(.*)/$ index.php?id=$1 [QSA,L] RewriteRule ^post/(.*)$ index.php?id=$1 [QSA,L]
? 关键说明:[QSA] 告诉 mod_rewrite:将原始请求中的查询字符串(如 ?page=2&sort=updated)自动追加到重写目标之后,等效于 index.php?id=122&page=2&sort=updated;[L](Last)表示该规则匹配后停止后续规则处理,避免意外覆盖,强烈建议添加;使用 ^...$ 锚定正则边界,提升匹配准确性与安全性;两条规则分别覆盖带尾部斜杠(post/122/)和不带斜杠(post/122)的场景。
? 在 index.php 中,你可以安全地获取全部参数:
⚠️ 注意事项:
- 确保 Apache 已启用 mod_rewrite 模块且站点允许 .htaccess 覆盖(AllowOverride All);
- 若使用 Nginx,请勿照搬 Apache 规则——Nginx 需用 try_files + query_string 机制实现等效功能;
- 避免过度依赖正则捕获 (.*) 处理复杂路径,生产环境建议使用更精确的模式(如 (\d+) 匹配纯数字 ID)以增强安全性与性能;
- 开启 RewriteLog(Apache 2.2)或使用 LogLevel alert rewrite:trace3(Apache 2.4+)可调试重写过程。
总结:[QSA] 是实现“友好 URL + 完整 GET 支持”的关键标志。它不是可选项,而是 RESTful 风格 PHP 路由的基础设施级配置。正确使用后,你的分页、筛选、排序等依赖查询参数的功能将无缝兼容 SEO 友好地址。










