【问题标题】:mod_rewrite and pretty urlsmod_rewrite 和漂亮的网址
【发布时间】:2011-02-04 07:28:01
【问题描述】:

我想要达到的目标:

1) http://localhost/en/script.php?param1=random 映射到 http://localhost/script.php?param1=random&language=English

  • 这必须始终有效。

2) http://localhost/en/random/text/here 将映射到 http://localhost/categories.php?term=random/text/here

  • 如果 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)

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

【问题讨论】:

    标签: apache mod-rewrite friendly-url


    【解决方案1】:

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

    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]
    

    【讨论】:

    • 效果很好,但由于某种原因,如果 URL 是 localhost/en/sales/subcategory,这是传递给 catagories.php 的参数:array(2) { ["terms"]=> string(35 ) "sales/subcategory/sales/subcategory" ["lang"]=> string(7) "English" } 有什么想法吗?
    • 在语言规则中添加 L 似乎已经解决了这个问题。
    • @Peeter:[L] 标志将跳过“类别”规则。对于不映射到文件的 URL,尾随路径组件存储为路径信息。 Apache 可能会加倍组件以尝试保留路径信息。尝试将丢弃路径信息标志(“DPI”)添加到语言规则(请参阅更新的代码)。
    【解决方案2】:

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

    还有

    %{QUERY_STRING}
    

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

    尝试做:

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

    【讨论】:

    • [L] 表示规则是最后执行的,就像您要查找的内容始终在您查找的最后一个位置一样。如果这就是您的意思,该标志不会更改评估顺序。
    • 以@Peeter 所做的方式,永远不会达到语言规则,简单。
    【解决方案3】:

    对于substr问题,你可以试试absolute paths:

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

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

    另外,我可能会吹毛求疵,但如果您在 PHP 中基于语言代码、404 不存在的语言并使用了语言评估,那岂不是更容易

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

    编辑:取决于你有多少脚本,你不能这样做:

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

    = 有可以访问的管道列表文件吗?

    【讨论】:

    • 替代问题开始于 RewriteCond %{REQUEST_FILENAME} !-f/RewriteCond %{REQUEST_FILENAME} !-d 它应该重定向到 categories.php?lang=English IF /en/this/here/不/不/匹配/a/脚本。如果我加载像 en/index.php 这样的 URL,它也会映射到 categories.php?lang=English,因为 en/index.php 不存在。
    猜你喜欢
    • 1970-01-01
    • 2012-10-18
    • 1970-01-01
    • 1970-01-01
    • 2011-09-19
    • 2014-04-22
    • 2012-03-07
    • 1970-01-01
    • 2012-01-01
    相关资源
    最近更新 更多