You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

mod_rewrite使用[N,QSA]时%1变量未更新致GET数组异常问题

mod_rewrite循环中%1变量未更新的问题分析与解决

问题场景

你编写的mod_rewrite脚本意图移除不存在的路径段,并将这些路径段以数组形式传递给PHP脚本,但实际运行时,$_GET['folder']数组的所有元素都是第一个路径段的值(比如['this','this','this','this']),而非预期的['this','folder','isnt','real']。原代码如下:

RewriteEngine On

LogLevel alert rewrite:trace3

# 当前请求指向的文件/文件夹是否不存在?
RewriteCond  /var/www/vhosts/example.org/httpdocs/fswtest%{REQUEST_FILENAME} !-f
RewriteCond  /var/www/vhosts/example.org/httpdocs/fswtest%{REQUEST_FILENAME} !-d
# URL中是否存在文件夹?获取列表中的第一个
RewriteCond %{REQUEST_URI} /([^/]+)/
# 仅从REQUEST_URI中移除第一个文件夹并重新开始
RewriteRule ./(.*) /$1?folder[]=%1 [N,QSA]

问题原因

核心问题出在RewriteCond的反向引用(%1)在[N]循环中不会重新更新:

  • 当使用[N]标志触发循环时,Apache会重新执行整个重写规则集,但RewriteCond中的捕获组(%1)是在规则集第一次执行时捕获的初始值,后续循环不会重新匹配RewriteCond的正则表达式来更新%1。
  • 简单说,%1被缓存成了第一次匹配到的this,后续循环复用了这个值,导致每次添加到数组的都是同一个字符串。

解决方案

把路径段的捕获逻辑从RewriteCond转移到RewriteRule中,利用RewriteRule的捕获组($1、$2等)——这些捕获组会在每次循环时基于当前更新后的URI重新计算:

RewriteEngine On
LogLevel alert rewrite:trace3

# 当前请求指向的文件/文件夹是否不存在?
RewriteCond  /var/www/vhosts/example.org/httpdocs/fswtest%{REQUEST_FILENAME} !-f
RewriteCond  /var/www/vhosts/example.org/httpdocs/fswtest%{REQUEST_FILENAME} !-d
# 匹配并捕获当前URI的第一个路径段,移除后继续循环
RewriteRule ^/([^/]+)/(.*)$ /$2?folder[]=$1 [N,QSA]

工作原理

  1. 第一次循环:匹配/this/folder/isnt/real/whatever.php,捕获$1=this,重写为/folder/isnt/real/whatever.php?folder[]=this,触发循环。
  2. 第二次循环:匹配/folder/isnt/real/whatever.php,捕获$1=folder,重写为/isnt/real/whatever.php?folder[]=this&folder[]=folder,触发循环。
  3. 重复此过程,直到URI变为/whatever.php,此时检查文件存在,循环停止。最终$_GET['folder']会得到预期的数组['this','folder','isnt','real']。

内容的提问来源于stack exchange,提问作者Lance McDonald

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 21:30:24