Apache mod_重写和漂亮的URL

Apache mod_重写和漂亮的URL,apache,mod-rewrite,friendly-url,Apache,Mod Rewrite,Friendly Url,我正在努力实现的目标: 1) 映射到 这必须一直有效 2) 将映射到 如果random/text/here是404,这必须起作用 我现在所拥有的: RewriteEngine on RewriteCond substr(%{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^en/(.+)$ categories.php?lang=English&terms=$1 [L] RewriteCo

我正在努力实现的目标:

1) 映射到

  • 这必须一直有效
2) 将映射到

  • 如果random/text/here是404,这必须起作用
我现在所拥有的:

RewriteEngine on
RewriteCond substr(%{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^en/(.+)$ categories.php?lang=English&terms=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ee/(.+)$ categories.php?lang=Estonian&terms=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^fi/(.+)$ categories.php?lang=Finnish&terms=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ru/(.+)$ categories.php?lang=Russian&terms=$1 [L]

RewriteRule ^en/(.*) $1?lang=English [QSA]
RewriteRule ^ee/(.*) $1?lang=Estonian [QSA]
RewriteRule ^ru/(.*) $1?lang=Russian [QSA]
RewriteRule ^fi/(.*) $1?lang=Finnish [QSA]
问题是:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d 
它应该重定向到categories.php?lang=English IF/en/this/here/does/not/match/a/script。如果我加载像en/index.php这样的URL,它也会被映射到categories.php?lang=English,因为en/index.php不存在

我的想法是:

substr(%%{REQUEST_FILENAME},3)将修复我的问题(因为当前/ee/index.php实际上映射到了/ee/index.php,而不仅仅是/index.php)


不幸的是,我找不到操作字符串的方法:/

对于substr问题,您可以尝试
绝对路径

RewriteRule ^en/(.*) /$1?lang=English&%{QUERY_STRING}

此外,我可能会吹毛求疵,但如果您在PHP中基于语言代码、404’ed不存在的语言和使用的语言进行语言评估,不是会更容易吗

RewriteRule ^(.*?)/(.*) $2?lang=$1&%{QUERY_STRING}
编辑:根据您有多少脚本,您不能执行以下操作:

重写规则^(.*)/(script.php | other.php)$2?lang=$1[QSA]


=是否具有可访问的管道列表文件?

问题在于您正在使用L标志。这意味着该规则将是最后执行的

如果没有必要,添加QSA,您将获得添加到url末尾的所有参数

试着做:

RewriteRule ^en/(.*) $1?lang=English [QSA]

我认为是语言代码使URL映射到不存在的文件。切换这两个步骤,首先将语言代码移动到查询字符串。这还具有将关键字步骤简化为单个重写规则的附加优势,因为它们不再需要同时做两件事

RewriteRule ^en/(.*) $1?lang=English [QSA,DPI]
RewriteRule ^ee/(.*) $1?lang=Estonian [QSA,DPI]
RewriteRule ^ru/(.*) $1?lang=Russian [QSA,DPI]
RewriteRule ^fi/(.*) $1?lang=Finnish [QSA,DPI]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ categories.php?terms=$1 [L,QSA]

替换问题从RewriteCond%{REQUEST_FILENAME}开始-f/RewriteCond%{REQUEST_FILENAME}-d它应该重定向到categories.php?lang=English IF/en/this/here/does/not/match/a/script。如果我加载一个像en/index.php这样的URL,它也会被映射到categories.php?lang=English,因为en/index.php不存在。
[L]
意味着规则是最后一个执行的规则,就像你要查找的东西总是在最后一个地方一样。如果这是你的意思,那么这个标志不会改变求值顺序。就像@Peeter那样,语言规则永远也达不到,很简单。这很好,但由于某种原因,如果URL是,这就是传递给catagories的参数。php:array(2){[“terms”]=>string(35)“sales/subcategory/sales/subcategory”[“lang”]=>string(7)“English”}有什么想法吗?在语言规则中添加L似乎已经解决了这个问题。@Peeter:L标志将跳过“类别”规则。对于不映射到文件的URL,尾部路径组件存储为路径信息。Apache可能将组件加倍,以试图保留路径信息。尝试将丢弃路径信息标志(“DPI”)添加到语言规则中(请参阅更新的代码)。
RewriteRule ^en/(.*) $1?lang=English [QSA]
RewriteRule ^en/(.*) $1?lang=English [QSA,DPI]
RewriteRule ^ee/(.*) $1?lang=Estonian [QSA,DPI]
RewriteRule ^ru/(.*) $1?lang=Russian [QSA,DPI]
RewriteRule ^fi/(.*) $1?lang=Finnish [QSA,DPI]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ categories.php?terms=$1 [L,QSA]