htaccess RewriteCond:为什么服务器变量本身不匹配?

时间:2016-02-17 23:38:20

标签: regex .htaccess url-rewriting rewrite bootstrapping

也许更好的问题是,有没有办法在匹配字符串中使用服务器变量?

例如,我无法理解为什么这不匹配:

RewriteCond %{REQUEST_URI} %{REQUEST_URI} 

首先,两点。

  1. 我知道这种情况服务器没有任何意义。
  2. 我知道我对htaccess和regex都知之甚少。
  3. 我想要的是通常将此网址 www.example.com/dir/path/info 转换为 www.example.com/dir?foo=/path/info for bootstrapping。

    我尝试通过从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。

2 个答案:

答案 0 :(得分:3)

重写模式参数只允许使用正则表达式(因此Condpattern还有用于测试和比较的特殊标志):

RewriteCond TestString CondPattern
RewriteRule 模式 替换

%{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=/$1&path=/$2 [L]

另外两个例子

的Sample1

RewriteBase /
RewriteRule ^(.+/)?index.php(/.+) index.php?dir=/$1&path=$2 [R,L]

样品2

RewriteBase /
RewriteRule ^((.+/)?index.php)(/.+) $1?path=$3 [R,L]

样品3

RewriteBase /
RewriteRule ^(.+/)?(.+\.php)(/.+) $1$2?foo=$3 [R,L]

这些都是外部重写,因此您可以在浏览器地址中看到结果。要恢复内部重写,只需删除[R]标志

答案 1 :(得分:2)

好的,我找到了实现这一目标的方法。

基本上我试图比较两个服务器变量。 htaccess不会这样做。我想提取一个指向实际文件或文件夹的“漂亮”网址的一部分。变量$ {SCRIPT_URL}应该这样做,但它要么折旧,要么不可靠。解决方法是将两个变量放在测试字符串中,并使用正则表达式返回引用来查找重复点。

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI}%{PATH_INFO} (.*?)(/.+)\2$  
RewriteRule ^(.*)$ %1.php?strappath=%2 [QSA,END]

在上面的示例中,%1将是文件的uri,%2将是URI之后的剩余路径,重复%{PATH_INFO}。

在没有额外路径信息的情况下遵循此规则

RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)$ $1.php [QSA,END]

如果找不到.php文件,我想要该目录的索引,并将未找到的文件名添加到pathinfo。这有点棘手。

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} ^(.*?)(/.+)\2$ [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 ^(.+)$ $1/index.php [QSA,END]

我怀疑是否有人发现这有用但我已经看到这个问题的变化一遍又一遍地问,没有给出有效的解决方案。