【问题标题】:Detecting language and keeping current url schema检测语言并保持当前的 url 架构
【发布时间】:2014-04-07 19:35:43
【问题描述】:

目前我的网站中只有一种语言,

我通过 .htaccess 实现了友好的 url,例如:

RewriteRule ^post/(.+)/(.+) post.php?id=$2&friendly=1

所以:

domain.com 是主页,domain.com/the-title/5 是 ID 为 5 的帖子的页面。

现在我想将其设为默认语言网址,例如,下一种语言是:

domain.com/es 是主页,domain.com/es/the-title/6 是 ID 为 6 的帖子的页面。 (但以前的规则也应该有效)

问题是,

我应该如何调整我的(或其他)重写规则以检查 url 的前 2 个字符(第一次拆分)并将其添加为参数,例如:&lan=es,如果未找到则不要添加这个参数?

让我们说:

^post/(.+)/(.+) post.php?id=$2&friendly=1(英文)

^es/post/(.+)/(.+) post.php?id=$2&friendly=1&lan=es(西班牙语)

但如果可能的话,

  • 要使用更多语言(并在需要时添加额外参数),
  • 仅使用其他规则,例如:

^es/photo/(.+)/(.+) photo.php?id=$2&friendly=1&lan=es(西班牙语)

有什么建议吗?

【问题讨论】:

  • 与您的其他参数相同:^(..)/post/(.+)/(.+) post.php?id=$3&friendly=$2&lan=$1 (..) 表示正好 2 个字符。
  • @njzk2 好的,谢谢!问题是我不想为当前(默认)语言添加 slug 的拆分,有什么想法吗?
  • 您可以使用rewriteCond 来检查网址中的语言参数。

标签: php .htaccess rewrite iso


【解决方案1】:

这样的事情可能会奏效。我尚未对其进行测试,但您可以使用 RewriteCond 检查 uri 的特定结构,如果匹配,请使用以下规则。如果没有,则继续原来的规则。

#Does the uri match 2 characters followed by /post/?
RewriteCond %{REQUEST_URI} ^../post/
#then use this rule and stop processing rules
RewriteRule ^(..)/post/(.+)/(.+) post.php?id=$3&friendly=1&lan=$1 [L]

#Else use this rule
RewriteRule ^post/(.+)/(.+) post.php?id=$2&friendly=1&lan=en

编辑:我在第二条规则的末尾添加了默认语言。这样总有一个$_GET['lan'] 参数。您可以将其关闭并在 php.ini 中设置默认值。您的选择,没有区别。

【讨论】:

    【解决方案2】:

    我只能用建议来回答你,因为我们需要更多背景信息...

    1. 使用默认页面临时重定向 (302) 到默认语言或用户语言。
    2. 始终使用相同的方案从相同的模式中获取语言 (http://mydomain.com/en/mypage.php)
    3. 如果您有大量公众或内容较多,请使用完整的语言代码,例如 en_US、fr_FR、fr_CA ...
    4. 在您的正则表达式中首选否定搜索以避免捕获以下字符,例如“before/([^/]+)/after”,在某些情况下,这是强制性的。
    5. 如果您没有语言信息,说明用户不是来自有效的 url,请将他重定向到包含语言信息(默认或用户语言)的页面。
    6. 如果用户使用直接php链接,请将他重定向到官方链接,以避免重复内容。您可以使用 $_SERVER['REQUEST_URI'] 来检查它。
    7. 使用框架来管理它,或者至少使用一个基础来控制路线。

    根据这些建议,您只能对所有网站使用以下重写规则:

    RewriteRule ^([^\/]+)/([^\.]+)\.([\.]+)$ index.php?lang=$1&route=$2&format=$3 [L,QSA]
    

    在这里我捕获了语言(es、en、en_US、fr...)、路线(post/5、gotabeer、cats/postit/thumb/2)和格式(html、json、jpeg... )。 (我没有尝试重写规则,但它应该可以工作)

    【讨论】:

      【解决方案3】:

      以下是我的建议:

      RewriteRule ^/?((en|es)/)?post/(.+)/(.+)$ post.php?id=$4&friendly=1&lan=$2
      

      /? 允许在字符串开头使用可选的正斜杠。这使得规则可以在 htaccess 目录联系人和 httpd.conf 服务器上下文之间互换

      ((en|es)/)? 允许可选地指定两种可接受的语言代码之一。

      请注意,我没有建议语言部分使用通配符,因为我假设您只使用已知的语言子集,因此使用已知语言代码以外的其他内容(或丢失整个内容)应该落入处理其他规则(或可能导致 404)。

      如果不是这种情况,您可以将正则表达式的第一部分从 (en|es) 更改为 (.{2})(如果您希望恰好两个字符),或者如果您希望还处理语言代码(如 es-ES),则可能更改为 (.{2}(-.{2})) .

      【讨论】:

      • 这与我正在寻找的内容非常接近,谢谢!如果第一个 slug (en|es|..) 是已知的,有没有办法添加一个额外的参数,无论 url 是什么?而且,如果它不存在,它也必须工作。它实际上可以这样,但这样我就不必为帖子、照片、任何帖子类型、.. 实现它
      • @ToniMichelCaubet 在这种情况下,lan 参数将始终被传递。如果存在enes 的值,将为参数指定,或者如果未指定enes,则参数将为空(即lan=)。当值存在和不存在时,您的 post.php 脚本应该能够处理这两种情况。 ((en|es)/)? 周围的外括号和问号允许该部分 URI 是可选的。
      • 好的,所以我可以通过添加((en|es|any-other-language-i-want))? 来编辑当前规则,而不是按语言添加额外规则,我可以保留当前的 ​​url 架构,但无论如何我都会检查参数,对吗?
      • @ToniMichelCaubet 正确。
      • @ToniMichelCaubet 您的代码绝对需要查找$_GET['lan'] 为空的情况。比如:if (empty($_GET['lan'])) { $language = 'en'; } else { $language = $_GET['lan']; }
      【解决方案4】:

      这应该适合你:

      RewriteEngine On
      
      RewriteRule ^([a-z]{2})/post/([^/]+)/([0-9]+)/?$ post.php?id=$3&friendly=1&lan=$1 [L,QSA]
      
      RewriteRule ^post/([^/]+)/([0-9]+)/?$ post.php?id=$2&friendly=1&lan=en [L,QSA]
      

      【讨论】:

      • 嗨!我想删除 post 部分并将其用于任何 URL,如果它没有任何 2 个字符 + / 则不发送参数 lan (添加,它不应该覆盖现有的),否则它是(但对于任何 URL)
      • 抱歉没有完全理解您的评论。你能用一些例子澄清一下吗?您想在浏览器中显示哪个 URL,哪个应该是内部 URL?
      猜你喜欢
      • 2010-11-27
      • 1970-01-01
      • 1970-01-01
      • 2010-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-10
      相关资源
      最近更新 更多