htaccess更改多变量url

时间:2013-12-07 11:30:51

标签: php .htaccess mod-rewrite get

我有一个带有一个或多个get变量的php页面,并且变量顺序可以因不同的进程而不同

www.lorem.com/ipsum.php?var1=aaa&var2=bbb&var3=ccc
www.lorem.com/ipsum.php?var2=bbb&var3=ccc
www.lorem.com/ipsum.php?var2=bbb&var3=ccc&var1=aaa

我想为所有类型的进程重写部分网址

www.lorem.com/ipsum/v1_aaa-v2_bbb-v3_ccc
www.lorem.com/ipsum/v2_bbb-v3_ccc
www.lorem.com/ipsum/v2_bbb-v3_ccc-v1_aaa

如何为变更var1 = aaa part写入重写规则到v1_aaa 和&去 - 也是ipsum.php?到ipsum /

我想学习如何写作。

1 个答案:

答案 0 :(得分:1)

你要做的事情并不简单。您要做的事情可以分为两部分:

  1. 从页面
  2. 中删除.php扩展程序
  3. 将查询字符串转换为key-value对。我使用-字符作为分隔符
  4. 当将网址重写为友好的网址时,您需要始终记住,您需要能够在内部将其重写回原始网址,否则无法显示网页。

    .htaccess应该是什么

    您需要按照以下.htaccess的规定执行某些操作。我将尝试在代码下面解释一些。

    #External redirect
    RewriteCond %{THE_REQUEST} \.php
    RewriteRule ^(.*)\.php$ $1 [E=redirflag:1]
    
    RewriteCond %{ENV:redirflag} =1
    RewriteCond %{QUERY_STRING} ^([^=]+)=([^&]+)(&(.*)|)$
    RewriteRule ^(.*)/(ipsum|otherpage|test)(/.*)?$ $1/$2$3/%1-%2?%4 [E=redirflag:1,N]
    
    RewriteCond %{ENV:redirflag} =1
    RewriteRule ^(.*)$ /$1 [R,L,E=!redirflag]
    
    #Internal rewrite
    RewriteRule ^(.*)/([^-]+)-(.+)/?$ $1?$2=$3 [QSA,N,DPI]
    
    RewriteCond %{REQUEST_URI} !\.php$
    RewriteRule ^(.*)$ /$1.php [L]
    

    仔细查看外部重定向

    让我们仔细看看会发生什么。第一条规则是从网址中删除.php扩展名。我们使用%{THE_REQUEST}来确保外部请求中存在某个.php。如果我们不这样做,我们将创建一个无限循环。因为我们想在重定向之前做一些其他的重写,所以我设置了一个环境变量(docs)。 $1被同一行上的第一个捕获组取代。

    第二条规则是将所有键值对重写为对网址的/key-value/添加。它仅适用于包含ipsumotherpagetest的网址(不一定以其结尾)。第一个条件是检查我在第一个规则中设置的标志是否为1。这意味着如果第一条规则不匹配,我也不符合这条规则。请注意,我使用=1来检查变量是否等于字符串1,并且不将其视为正则表达式。 (docs)。第二个条件中的正则表达式匹配捕获组1中的键,捕获组2中的值,如果后面有更多键和值,则匹配捕获组4中的值。%1和实际规则中的类似变量将在最后一次重写条件中被相应的捕获组替换。 N标志将从一开始就重新启动.htaccess,直到此规则不再匹配为止。

    第三条规则会将客户端重定向到我们刚刚重写的网址。 R是临时重定向。如果您对所有网址感到满意,请将其设置为R=301,以使其成为永久重定向。 E=!redirflag将删除该环境变量。

    仔细查看内部重写

    客户端使用seo友好的URL向您的服务器发出新请求。我们需要在内部将其重写回一个对服务器实际有用的URL。在url的末尾,我们有(或可能有)键值对,所以让我们从将它们重写回查询字符串中的键值对开始。 QSA标志将当前查询字符串附加到我们已有的查询字符串。我们已经看到的N标志。 DPI标志是“丢弃路径信息”,用于防止在网址末尾附加重复路径,从而导致无限循环。如果要省略这一点,你的服务器会锁定,错误日志会非常广泛,我相信Apache最终会崩溃。

    第二条规则只会在第一条规则不再匹配时匹配。在url的末尾没有更多的键值对,所以我们最终在我们删除php扩展的位置。我们再来补充一下。该规则的条件是uri尚未以.php结尾。如果不存在这种情况,它会继续附加.php,你最终会得到像test.php.php.php.php.php这样的东西(我们不希望这样)。

    进一步阅读

    首先,请阅读mod_rewrite的{​​{3}}。它非常详细,如果您不理解与其相关的代码中的某些内容,它是一个很好的参考指南。

    mod_rewrite使用类似perl的正则表达式语法。如果您无法理解某个正则表达式的含义,请在其旁边按住PREG / PCRE语法表。在尝试理解或写东西时,这应该有很多帮助。在线preg regex工具可以极大地帮助查看某个表达式的作用与不匹配。请记住,虽然应该和不应该转义的内容可能存在差异。