迁移至PHP8后.htaccess Rewrite规则失效问题求助
PHP7迁移PHP8后.htaccess URL重写异常解决方案
我的.htaccess基础配置如下:
Options +FollowSymLinks RewriteEngine on RewriteBase /baba/ ErrorDocument 404 http://localhost/baba/404.php
1. 搜索页面重写问题
仅用单条规则时正常运行:
RewriteRule ^s/([\w-]+)/(.*)$ search.php?feq=$1&key=$2 [QSA,L]
但添加以下两条规则后,搜索页面出现404错误:
RewriteRule ^s/([\w-]+)/(.*)/(.*)$ search.php?feq=$1&city=$2&key=$3 [QSA,L] RewriteRule ^s/([\w-]+)/(.*)/(.*)/(.*)$ search.php?feq=$1&pro=$2&city=$3&key=$4 [QSA,L]
问题根源
- 规则顺序错误:短路径规则放在前面,会优先匹配所有以
s/xxx/开头的URL(包括更长的3段、4段路径),因为(.*)是贪婪匹配,会吃掉后面的斜杠和内容,导致长规则永远不会触发。 (.*)匹配范围过宽:会包含斜杠字符,导致不同规则之间互相干扰。
修正后的规则
把更长的规则放在前面,同时用[^/]+代替(.*),限制每个分段只匹配非斜杠字符:
# 匹配4段路径:s/feq/pro/city/key RewriteRule ^s/([\w-]+)/([^/]+)/([^/]+)/([^/]+)$ search.php?feq=$1&pro=$2&city=$3&key=$4 [QSA,L] # 匹配3段路径:s/feq/city/key RewriteRule ^s/([\w-]+)/([^/]+)/([^/]+)$ search.php?feq=$1&city=$2&key=$3 [QSA,L] # 匹配2段路径:s/feq/key RewriteRule ^s/([\w-]+)/([^/]+)$ search.php?feq=$1&key=$2 [QSA,L]
2. 着陆页面重写问题
仅用单条规则时正常运行:
RewriteRule ^([\w-]+)$ land.php?name=$1 [QSA,L]
添加以下规则后,着陆页面出现404错误,且CSS、图片等静态资源停止加载:
RewriteRule ^([\w-]+)/(.*)/(.*)$ land.php?name=$1&pro=$2&city=$3 [QSA,L] RewriteRule ^([\w-]+)/(.*)$ land.php?name=$1&key=$2 [QSA,L] RewriteRule ^([\w-]+)/(.*)/(.*) land.php?name=$1&city=$2&key=$3 [QSA,L] RewriteRule ^([\w-]+)/(.*)/(.*)/(.*)$ land.php?name=$1&pro=$2&city=$3&key=$4 [QSA,L]
问题根源
- 规则顺序混乱:短规则插在中间,且存在重复规则(第三条和第一条都是3段路径,还缺了结尾的
$),导致匹配逻辑混乱。 (.*)贪婪匹配:同样会吃掉斜杠,引发错误匹配。- 静态资源被误重写:CSS、图片等文件的URL被当成着陆页面路径,被规则重定向到land.php,导致加载失败。
修正后的规则
- 先添加排除静态文件的规则,避免资源被误重写;
- 按路径长度从长到短排序规则;
- 用
[^/]+代替(.*):
# 排除静态资源:直接访问CSS、JS、图片等文件时跳过重写 RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^ - [L] # 匹配4段路径:name/pro/city/key RewriteRule ^([\w-]+)/([^/]+)/([^/]+)/([^/]+)$ land.php?name=$1&pro=$2&city=$3&key=$4 [QSA,L] # 匹配3段路径:name/pro/city RewriteRule ^([\w-]+)/([^/]+)/([^/]+)$ land.php?name=$1&pro=$2&city=$3 [QSA,L] # 匹配3段路径:name/city/key(若业务需要这条,需确保和上面的3段规则无冲突,否则只会执行先出现的那条) RewriteRule ^([\w-]+)/([^/]+)/([^/]+)$ land.php?name=$1&city=$2&key=$3 [QSA,L] # 匹配2段路径:name/key RewriteRule ^([\w-]+)/([^/]+)$ land.php?name=$1&key=$2 [QSA,L] # 匹配1段路径:name RewriteRule ^([\w-]+)$ land.php?name=$1 [QSA,L]
注意:如果两条3段路径规则的业务逻辑冲突,需要通过特定前缀或其他标识调整正则,避免匹配冲突。
另外,静态资源加载问题也可以通过在页面中使用绝对路径引用资源解决,比如把<link href="css/style.css">改成<link href="/baba/css/style.css">,这样不管URL层级如何,都能正确定位资源。
内容的提问来源于stack exchange,提问作者Deepak Dholiyan
相关产品推荐
相关产品推荐

