如何通过.htaccess的Rewrite规则隐藏.php后缀及GET参数id
问题原因分析
你触发500错误的核心原因有两点:
RewriteRule仅能匹配URL的路径部分,不会识别?后面的查询参数,你添加的RewriteRule ^news.php?id=([0-9]+) /news/$1 [NC,L]属于无效匹配规则。- 规则顺序错误:带参数的特殊路由规则必须放在通用
.php后缀隐藏规则之前,否则会被通用规则提前拦截,甚至触发无限重写循环。
正确完整配置
RewriteEngine On # 旧地址自动跳转美化格式,避免重复收录 RewriteCond %{QUERY_STRING} ^id=([0-9]+)$ RewriteRule ^news\.php$ /news/%1? [R=301,NC,L] # 美化地址内部重写到实际PHP文件 RewriteRule ^news/([0-9]+)$ /news.php?id=$1 [NC,L] # 原有通用.php后缀隐藏规则 RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}\.php -f RewriteRule ^(.*)$ $1.php [NC,L]
规则说明
- 第一条规则负责将用户直接访问的旧地址
/news.php?id=45自动301跳转到美化后的/news/45格式,末尾的?作用是清除跳转后URL残留的查询字符串,避免参数出现在地址栏。 - 第二条规则是内部重写,用户访问
/news/45时,服务器会在后台指向news.php?id=45,地址栏不会发生变化,PHP代码可正常通过$_GET['id']获取参数值。 - 原有通用后缀隐藏规则放在最后,保证特殊路由规则优先匹配生效,不会被通用逻辑覆盖。
注意事项
- 若有其他同类型参数路由(比如
/article/123对应article.php?id=123),可仿照前两条规则的格式,在通用规则前新增对应配置即可。 - 调试阶段建议将
R=301改为R=302,避免浏览器缓存旧的301规则导致调试异常,确认规则生效后再改回301即可。
内容的提问来源于stack exchange,提问作者Mohammed Juma
相关产品推荐
相关产品推荐

