【问题标题】:mod_rewrite for URL with more than one variable具有多个变量的 URL 的 mod_rewrite
【发布时间】:2014-08-15 15:19:19
【问题描述】:

您好,我正在尝试关注 Mod_Rewrite for URL with multiple variables 并对其进行编辑以适合我的网站,但我在互联网上搜索了一些问题,但找不到任何有用的东西

我正在尝试将 example.com/editor/windows/chrome 变成这个 example.com?app=editor&os=windows&browser=chrome

有什么想法吗?

我当前的 .htaccess 文件:

# Various rewrite rules.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9_-]+)/?$ index.php?app=$1 [QSA]
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/?$ index.php?app=$1&os=$2&browser=$3 [QSA]
</IfModule>

我可以让它部分工作到 example.com/editor/windows,但不能让第三个包含浏览器

【问题讨论】:

    标签: .htaccess mod-rewrite


    【解决方案1】:

    您的第三条规则不包括浏览器的捕获组。缺少此语句:

    RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)$ index.php?app=$1&os=$2&browser=$3 [QSA]
    

    从上到下应用重写规则,直到找到 [L]。因此,在您的问题中,两个规则都适用(这可能会导致性能不佳)。

    一个更干净的版本是,

    # Various rewrite rules.
    <IfModule mod_rewrite.c>
    RewriteEngine on
    
    # don't rewrite URLs for existing files, directories or links
    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d [OR]
    RewriteCond %{REQUEST_FILENAME} -l
    RewriteRule .* - [L]
    
    # now match the URIs according to OP needs
    # Redirect example.com/editor and example.com/editor/ to example.com/index.php?app=editor and stop after this rule
    RewriteRule ^([a-zA-Z0-9_-]+)/?$ index.php?app=$1 [QSA,L]
    # Redirect example.com/editor/windows and example.com/editor/windows/ to example.com/index.php?app=editor&os=windows and stop after this rule
    RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/?$ index.php?app=$1&os=$2 [QSA,L]
    # Redirect example.com/editor/windows/chrome and example.com/editor/windows/chrome/ to example.com/index.php?app=editor&os=windows&browser=chrome and stop after this rule
    RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/?$ index.php?app=$1&os=$2&browser=$3 [QSA,L]
    </IfModule>
    

    但是,最后三个RewriteRule 规则也可以编译为一个:

    RewriteRule ^([a-zA-Z0-9_-]+)(?:/([a-zA-Z0-9_-]+)(?:/([a-zA-Z0-9_-]+)))/?$ index.php?app=$1&os=$2&browser=$3 [QSA,L]
    

    【讨论】:

    • 您应该解释条件如何应用于规则,而不是使错误更加复杂。最简单的方法是否定 conds 和 [OR] 它们,因此第一个 cond 变为 RewriteCond %{REQUEST_FILENAME} -f [OR],然后通过 RewriteRule ^ - [LAST, NC] 跟随它们
    • 这是一个直截了当的问题,为什么第三种情况不匹配。其他规则向我表明,OP 知道这些其他规则的含义。
    • @TerryE 我不明白为什么你没有先讨论就立即给了我-1(请参阅本页上的其他答案)。我努力解释它的原因(与其他答案相反)
    • 我很容易翻转-1。我仍然会因为投反对票而受到惩罚,但你会记住我的观点。但我还是更喜欢 Jon Lin 的解决方案。
    【解决方案2】:

    只要您不介意有空白的$_GET[] 变量,您就可以将其简化为一条规则。也不是说您有 2 个条件来检查 !-f!-d。这些条件仅适用于紧随其后的规则,除非您重复该条件,否则不会适用于任何其他规则。

    所以你可以试试:

    # Various rewrite rules.
    <IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^([a-zA-Z0-9_-]+)(?:/([a-zA-Z0-9_-]+)|)(?:/([a-zA-Z0-9_-]+)|)/?$ index.php?app=$1&os=$2&browser=$3 [L,QSA]
    </IfModule>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-01
      • 1970-01-01
      • 2016-01-22
      相关资源
      最近更新 更多