我的应用程序有两个重写规则:
第一条规则是/chef/index.php
的规则:
/chef/name -> /chef/?id=1234
第二条规则是/recipes/index.php
的规则:
/r/name/nice-name-for-recipe ->
/recipes/?id=1234&nice_name=nice-name-for-recipe-name
这两个规则分开工作,但如果我启用了这两个规则:
我试图交换规则的顺序,但我仍然不能使它们都有效。
规则:
RewriteEngine On
RewriteRule ^([a-zA-Z0-9_-]+)/chef/$ $1 [QSA]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /chef/index.php?id=$1 [QSA]
RewriteRule ^([a-zA-Z0-9_-]+)/r/$ $1/$2 [QSA]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /recipes/index.php?id=$1&nice_name=$2 [QSA]
答案 0 :(得分:1)
在第一条规则中,您尝试匹配^([a-zA-Z0-9_-]+)/chef/$
。
/chef/$
表示它与以/chef/
结尾的网址匹配,
因为$
表示字符串的结尾,例如:
http://anything.dev/chef/
因此它与/chef/name/
不匹配,它与/chef/
匹配。
同样,您的第二条规则与/r/name/nice-name-for-recipe
不匹配,
它匹配/r/$
。
这些规则只是告诉apache回退到静态文件。 如果您需要提供静态文件,这很有用 但他们与这个问题无关。
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
所以你的规则大致只是:
RewriteRule ^(.*)$ /chef/index.php?id=$1 [QSA]
RewriteRule ^(.*)$ /recipes/index.php?id=$1&nice_name=$2 [QSA]
现在很清楚,为什么这些规则分开工作,但只有第二个规则才能合并。
它们都匹配^(.*)$
,即每个网址(静态文件的网址除外)。
因此,当把它们放在一起时,只有第二个获胜。
所以真正的规则效果是:
/chef/name ->
/chef/index.php?id=/chef/name&nice_name=
/r/name/nice-name-for-recipe ->
/chef/index.php?id=/r/name/nice-name-for-recipe&nice_name=
P.S。我认为这个问题的深层原因是:
您尝试编写正则表达式而不理解它们。
正则表达式语法很难理解。具体来说,$
都用作模式和变量前缀。
index.php
代码很脏。它不应该盲目地接受网址。如果index.php
出错,则这两条规则似乎不起作用。脏代码很难检测和定位问题,而且不安全(攻击者可以构建危险的特殊网址)。
由于RewriteRule ^(.*)$ /recipes/index.php?id=$1&nice_name=$2 [QSA]
未设置,您的IDE不足以警告您$2
。
答案 1 :(得分:0)
您写的是要将dev.website.com/chef/name
转换为dev.website.com/chef/?id=1234
。这不起作用,因为目标网址中的ID在源网址中不存在,因此您需要考虑如何在原始网址中包含该ID。
一旦您对其进行排序,我建议您阅读有关正则表达式的更多内容以修复mod_rewrite
规则。
这是测试和解释正则表达式的绝佳资源:https://regex101.com/