正则表达式捕获组为空,除非我使用 [QSA] 标志

Regex capture group is empty, unless I use the [QSA] flag

我正在制定一个重写规则,将 art/slug/... 重写为 art/.../?art=slug。我编写的规则有效,但仅在使用 [QSA].

时生成预期的查询字符串

规则的正上方是 RewriteCond %{REQUEST_FILENAME} !-f,以防止在重写的 url 与现有文件匹配后循环。

我已经测试了以下规则,并导航到 art/test/ $_GET 正在 var_dump 的地方。以下是结果:

RewriteRule ^art/([^/]*)/?(.*) art/?art= [L] 输出 'art' => string ''
RewriteRule ^art/([^/]*)/?(.*) art/?art= [QSA,L] 输出 'art' => string 'test'
RewriteRule ^art/([^/]*)/?(.*) art/?art=test [L] 输出 'art' => string 'test'

根据我的理解,QSA 是为了将 "original" 查询字符串附加到 "rewritten" 之后。
在我的情况下,我没有也不想要原始 url 中的任何查询字符串;它完全是在重写期间完成的,所以在第一个例子中我不明白为什么我的 art 键被设置为空,(虽然它不是未定义的)。

假设我误解了 QSA,并且它是生成任何查询字符串所必需的;那么在第三个示例中,如何在没有 QSA 标志的情况下对查询字符串的值进行硬编码?
删除 QSA 是否会以某种方式改变我的正则表达式的工作方式?


我是 运行 具有 WAMP 3.0.6 64 位、Apache 2.4.23 和 PHP 7.0.10

的本地服务器

我理解你的问题,你应该防止在你上面提到的所有情况下发生的循环,所以在重写之前你应该确保没有 query string ,否则所有的循环都会发生,这就是为什么你错过了第一行的 test .

在任何规则之前添加这个并再次测试:

RewriteCond %{QUERY_STRING} !^(.+)$