将多个 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 中的单个规则的主要内容,如果未能解决你的问题,请参考以下文章

将多个 numpy 数组组合成不同形状之一

将多个查询组合成一个查询

将多个目标组合成一个目标

将多个 SQL 查询组合成单个结果

将多个字典组合成一个字典[重复]

将多个 CustomUserControl 模板组合成一个模板