我有一个重写所有URL的.htaccess
文件。例如:
# Special urls
RewriteRule ^(article)/([^/]*)(?:/[^/]*)?$ /index.php?page=$1&keyword=$2 [L,QSA,NC]
RewriteRule ^(privacy)$ /index.php?page=legal&type=$1 [L,QSA,NC]
RewriteRule ^(imprint)$ /index.php?page=legal&type=$1 [L,QSA,NC]
# All urls
RewriteRule ^([0-9a-zA-Zs]+)$ /index.php?page=$1 [QSA]
现在我想在我的 URL 中集成一个语言参数。例如
- ➡
example.com/test
/index.php?page=test
- ➡
example.com/en/test
/index.php?lang=en&page=test
如何在不编辑所有RewriteRule
的情况下完成此操作?有没有办法检查example.com
后的部分是否与正则表达式匹配,附加查询参数并正常处理所有未来的规则?
是的,这是可能的。在现有规则之前添加以下规则:
# Add optional language URL param if present in the first path segment
RewriteRule ^(ww)/(.*) $2?lang=$1 [QSA,DPI]
更新:DPI
标志会丢弃原始路径信息,否则该路径信息将在重写后附加到 URL 路径。这将导致紧随其后的指令从不匹配到下一轮处理。(请参阅下面的更新,其中有更详细的介绍。
这假定语言代码始终为 2 个字符。
重写 URL 以从 URL 路径中删除语言路径段,并将其追加为lang
URL 参数。特别省略了L
标志,因此保留以下规则以匹配没有语言代码的 URL 路径。
由于以下规则已具有QSA
标志,因此将追加lang=
URL 参数。
但请注意,lang=en
参数追加在查询字符串的末尾,而不是前缀到开头,如示例中所示。
>UPDATE:似乎不仅附加了语言,还附加了页面名称。例如:example.com/de/index
结果为index?lang=de/index
通过将 DPI 添加到[QSA]
➡[QSA,DPI]
来解决
嗯嗯,是也不是...仅给定问题中所述的指令,这仍然应该在没有DPI
标志的情况下"工作"(尽管效率不高)。事实上,index?lang=de/index
似乎不可能作为生成的 URL(没有page
URL 参数)?其他指令可能会导致路径信息附加到查询字符串?需要注意的一点是,问题中陈述的最后一条规则缺少L
标志,因此随后的任何指令都可能被不必要地处理(甚至冲突)。但是,DPI
标志肯定是一个改进,应该添加。
详细地。。。
给定一个形式为/de/index
的请求,并且/de
不作为物理目录存在,那么请求的 URL-path 末尾的/index
部分是附加的路径名信息(path-info),并且在上面重写后附加到 URL 路径中(这确实是不可取的)。因此,形式/de/index
的请求被重写为index?lang=de
,在重新附加路径信息后变得index/index?lang=de
(请注意,它不会附加到查询字符串)。
生成的 URL 路径index/index
(附加路径信息)与后面的RewriteRule
指令不匹配。但是,重写引擎随后重新启动,此时(不必要地)添加的路径信息在下一轮处理之前自然会被丢弃。这会导致"正确"的index?lang=de
URL 被用作第二轮处理的输入。这与问题中陈述的最后一个规则匹配,请求最终被重写为/index.php?page=index&lang=de
。
因此,DPI
标志在这里不应该是它"工作"所必需的。但是,当然建议这样做,因为它避免了不必要的第二次通过重写引擎。使用DPI
标志时,路径信息不会在第一次重写后追加,因此 URL 路径将在第一次传递时与相应的规则匹配。