htaccess RewriteCond:为什么服务器变量不匹配自身?
htaccess RewriteCond: Why doesn't a server variable match itself?
也许更好的问题是,有没有办法在匹配字符串中使用服务器变量?
例如,我无法理解为什么这无法匹配:
RewriteCond %{REQUEST_URI} %{REQUEST_URI}
首先,两点。
- 我知道这种情况没有任何意义。
- 我知道我对 htaccess 和正则表达式知之甚少。
我想要的是将这个URLwww.example.com/dir/path/info一般地变成www.example .com/dir?foo=/path/info 用于引导。
我试图通过从 URL 中最深的实际目录中删除额外的路径信息来完成此操作。我正在尝试使用这段代码来测试前提:
RewriteEngine On
Options -Multiviews -Indexes +FollowSymLinks
RewriteBase /
DirectorySlash Off
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} (.+)%{PATH_INFO}
RewriteRule ^(.+?) index.php?dir=%1&path=%2 [L]
运气不好。为了排除故障,我将其简化为:
RewriteCond %{PATH_INFO} (.+)
RewriteRule ^(.+?) index.php?dir=%1 [L]
正如预期的那样,查询返回了 foo='/path/info'
所以我尝试了这个我认为无论如何都会匹配的:
RewriteCond %{PATH_INFO} %{PATH_INFO}
最后一次尝试失败了,我尝试捕获字符串:
RewriteCond %{PATH_INFO} (.+)
RewriteCond %{PATH_INFO} %1
那也没有找到让我百思不得其解的搭配。 %1 应该是完整的 %{PATH_INFO} 字符串。怎么会和自己不匹配???
我认为这无关紧要,但我在 FastCGI 的 Windows7 上使用 XAMPP。
重写 pattern 参数只允许正则表达式(Condpattern 也有用于测试和比较的特殊标志):
RewriteCond TestString CondPattern
重写规则模式替换
像 %{REQUEST_URI} 这样的服务器变量只能在 Teststring 和 Substitution 中使用。以下文档概述了这种用法:
http://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewritecond
http://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewriterule
如果这会进入你的主 .htaccess,也许试试:
RewriteCond %{REQUEST_URI} !index\.php$
RewriteRule ^([^/]+)/(.+)$ index.php?dir=/&path=/ [L]
再举两个例子:
示例 1
RewriteBase /
RewriteRule ^(.+/)?index.php(/.+) index.php?dir=/&path= [R,L]
示例 2
RewriteBase /
RewriteRule ^((.+/)?index.php)(/.+) ?path= [R,L]
示例 3
RewriteBase /
RewriteRule ^(.+/)?(.+\.php)(/.+) ?foo= [R,L]
这些都是外部重写所以你可以在浏览器地址看到结果。要恢复为内部重写,只需删除 [R] 标志
好的,我找到了实现这个目标的方法。
基本上我是想比较两个服务器变量。 htaccess 不会那样做。我想提取指向实际文件或文件夹的 "pretty" url 的一部分。变量 ${SCRIPT_URL} 应该这样做,但它要么贬值要么不可靠。解决方法是将两个变量都放在测试字符串中,并使用正则表达式反向引用来查找重复点。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI}%{PATH_INFO} (.*?)(/.+)$
RewriteRule ^(.*)$ %1.php?strappath=%2 [QSA,END]
在上面的示例中,%1 将是文件的 uri,%2 将是 URI 之后的剩余路径,重复 %{PATH_INFO}。
没有额外路径信息时遵循此规则
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)$ .php [QSA,END]
如果没有找到 .php 文件,我需要该目录的索引并将未找到的文件名添加到路径信息中。这有点棘手。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php !-f
RewriteCond %{REQUEST_FILENAME} ^(.*)(/.+)$
RewriteCond %1 -d
RewriteCond %1/index.php -f
RewriteCond %{REQUEST_URI}%{PATH_INFO} ^(.*?)(/.+)$ [OR]
RewriteCond %{REQUEST_URI} ^(/.+)(/.+)?$
RewriteCond %1 ^(.*)(/.+)$
RewriteRule ^(.*)$ %1/index.php?strappath=%2%{PATH_INFO} [QSA,END]
以上部分无法捕获直接指向具有 index.php 的现有文件夹的 url,因此要捕获那些:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_FILENAME}/index.php -f
RewriteCond ^(.+)$ /index.php [QSA,END]
我怀疑有人会觉得这个有用,但我看到这个问题的变体被一遍又一遍地问,但没有给出有效的解决方案。
也许更好的问题是,有没有办法在匹配字符串中使用服务器变量?
例如,我无法理解为什么这无法匹配:
RewriteCond %{REQUEST_URI} %{REQUEST_URI}
首先,两点。
- 我知道这种情况没有任何意义。
- 我知道我对 htaccess 和正则表达式知之甚少。
我想要的是将这个URLwww.example.com/dir/path/info一般地变成www.example .com/dir?foo=/path/info 用于引导。
我试图通过从 URL 中最深的实际目录中删除额外的路径信息来完成此操作。我正在尝试使用这段代码来测试前提:
RewriteEngine On
Options -Multiviews -Indexes +FollowSymLinks
RewriteBase /
DirectorySlash Off
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} (.+)%{PATH_INFO}
RewriteRule ^(.+?) index.php?dir=%1&path=%2 [L]
运气不好。为了排除故障,我将其简化为:
RewriteCond %{PATH_INFO} (.+)
RewriteRule ^(.+?) index.php?dir=%1 [L]
正如预期的那样,查询返回了 foo='/path/info'
所以我尝试了这个我认为无论如何都会匹配的: RewriteCond %{PATH_INFO} %{PATH_INFO}
最后一次尝试失败了,我尝试捕获字符串:
RewriteCond %{PATH_INFO} (.+)
RewriteCond %{PATH_INFO} %1
那也没有找到让我百思不得其解的搭配。 %1 应该是完整的 %{PATH_INFO} 字符串。怎么会和自己不匹配???
我认为这无关紧要,但我在 FastCGI 的 Windows7 上使用 XAMPP。
重写 pattern 参数只允许正则表达式(Condpattern 也有用于测试和比较的特殊标志):
RewriteCond TestString CondPattern
重写规则模式替换
像 %{REQUEST_URI} 这样的服务器变量只能在 Teststring 和 Substitution 中使用。以下文档概述了这种用法:
http://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewritecond http://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewriterule
如果这会进入你的主 .htaccess,也许试试:
RewriteCond %{REQUEST_URI} !index\.php$
RewriteRule ^([^/]+)/(.+)$ index.php?dir=/&path=/ [L]
再举两个例子:
示例 1
RewriteBase /
RewriteRule ^(.+/)?index.php(/.+) index.php?dir=/&path= [R,L]
示例 2
RewriteBase /
RewriteRule ^((.+/)?index.php)(/.+) ?path= [R,L]
示例 3
RewriteBase /
RewriteRule ^(.+/)?(.+\.php)(/.+) ?foo= [R,L]
这些都是外部重写所以你可以在浏览器地址看到结果。要恢复为内部重写,只需删除 [R] 标志
好的,我找到了实现这个目标的方法。
基本上我是想比较两个服务器变量。 htaccess 不会那样做。我想提取指向实际文件或文件夹的 "pretty" url 的一部分。变量 ${SCRIPT_URL} 应该这样做,但它要么贬值要么不可靠。解决方法是将两个变量都放在测试字符串中,并使用正则表达式反向引用来查找重复点。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI}%{PATH_INFO} (.*?)(/.+)$
RewriteRule ^(.*)$ %1.php?strappath=%2 [QSA,END]
在上面的示例中,%1 将是文件的 uri,%2 将是 URI 之后的剩余路径,重复 %{PATH_INFO}。
没有额外路径信息时遵循此规则
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)$ .php [QSA,END]
如果没有找到 .php 文件,我需要该目录的索引并将未找到的文件名添加到路径信息中。这有点棘手。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php !-f
RewriteCond %{REQUEST_FILENAME} ^(.*)(/.+)$
RewriteCond %1 -d
RewriteCond %1/index.php -f
RewriteCond %{REQUEST_URI}%{PATH_INFO} ^(.*?)(/.+)$ [OR]
RewriteCond %{REQUEST_URI} ^(/.+)(/.+)?$
RewriteCond %1 ^(.*)(/.+)$
RewriteRule ^(.*)$ %1/index.php?strappath=%2%{PATH_INFO} [QSA,END]
以上部分无法捕获直接指向具有 index.php 的现有文件夹的 url,因此要捕获那些:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_FILENAME}/index.php -f
RewriteCond ^(.+)$ /index.php [QSA,END]
我怀疑有人会觉得这个有用,但我看到这个问题的变体被一遍又一遍地问,但没有给出有效的解决方案。