将多个 RewriteRule 指令组合成 .htaccess 中的单个规则
Posted
技术标签:
【中文标题】将多个 RewriteRule 指令组合成 .htaccess 中的单个规则【英文标题】:Combine several RewriteRule directives into a single rule in .htaccess 【发布时间】:2021-11-29 13:50:30 【问题描述】:我在.htaccess
中有以下RewriteRule
指令:
RewriteRule ^work/([a-zA-z0-9\-]*).html$ work.php?go=$1 [L]
RewriteRule ^work/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*).html$ work.php?go=$1&sub=$2 [L]
RewriteRule ^work/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*).html$ work.php?go=$1&sub=$2&pid=$3 [L]
RewriteRule ^work/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*).html$ work.php?go=$1&sub=$2&pid=$3&pad=$4 [L]
RewriteRule ^work/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*)/([a-zA-z0-9\-]*).html$ work.php?go=$1&sub=$2&pid=$3&pad=$4&id=$5 [L]
一切正常。
但是有谁知道,我怎样才能把所有这行放在一行中作为一个规则?
【问题讨论】:
您为什么要这样做?结果将非常难以理解和维护。很少有好主意。 因为不幸的是我有很多它的变种,并且可以将其减少到五分之一(5x 工作到 1...)。 规则集的实现并不复杂、耗时。维护和错误跟踪是昂贵的。这两个主题遵循指数曲线。因此,您绝对希望保持这些简单,而不是规则集的实现或存储。 【参考方案1】:您不能将这些规则简化为一条规则并让它“完全”以相同的方式工作。在单个规则中,将始终定义所有 URL 参数(但可能为空)。使用您当前的规则集,仅在需要时才定义 URL 参数 - 细微差别。如果您可以接受这种细微的差异(您应该可以),那么这些规则可以简化为一条规则。
首先,我建议对您现有的正则表达式进行一些小改动:
我会假设最终的路径段,即。 .html
之前的“文件名”是强制性的。目前,您允许/work/.html
(这会导致go
URL 参数为空)。
其他 URL 参数应接受 1 个或多个字符,而不是 0 个或多个。无论如何,它实际上不会“匹配” 0 个字符,因为多个连续
RewriteRule
pattern 匹配的 URL 路径中的斜杠被减少。
我会简化您在路径段中匹配的正则表达式。从[a-zA-z0-9\-]
到[\w-]
。这与之前的匹配加上下划线 (_
)。在字符类的开头或结尾使用时,无需对文字连字符进行反斜杠转义。
由于您在所有路径段中匹配相同的模式,“组合”规则不会过于复杂,因为您可以附加另一个路径段并使其对于每个附加 URL 参数都是可选的(所有前面的路径段必须先匹配)。但是,如果您在每个路径段中匹配不同的正则表达式,它会复杂得多 - 这将涉及许多 嵌套 组以保持正确的匹配顺序。
考虑到以上几点,您的 5 条规则可以合并为以下一条规则:
RewriteRule ^work/([\w-]+)(?:/([\w-]+))?(?:/([\w-]+))?(?:/([\w-]+))?(?:/([\w-]+))?\.html$ work.php?go=$1&sub=$2&pid=$3&pad=$4&id=$5 [L]
在第一个强制路径段(即([\w-]+)
)之后,正则表达式(?:/([\w-]+))?
只是为每个额外的可选路径段附加。
这将导致以下重写:
/work/.html
- 未重写
/work/abc.html
-> work.php?go=abc&sub=&pid=&pad=&id=
/work/abc/def.html
-> work.php?go=abc&sub=def&pid=&pad=&id=
/work/abc/.html
- 未重写
/work/abc/def/ghi/jkl/mno.html
-> work.php?go=abc&sub=def&pid=ghi&pad=jkl&id=mno
/work/abc/def/ghi/jkl/mno/.html
- 未重写
/work/abc/def/ghi/jkl/mno/pqr.html
- 未重写
【讨论】:
谢谢,我会试试这些。是的,.html 之前的“文件名”是强制性的。 非常感谢,效果很好!以上是关于将多个 RewriteRule 指令组合成 .htaccess 中的单个规则的主要内容,如果未能解决你的问题,请参考以下文章