【问题标题】:Multi language PHP application: best practice?多语言 PHP 应用程序:最佳实践?
【发布时间】:2011-05-14 07:56:59
【问题描述】:

我想就我在 PHP MVC Web 应用程序上实现多语言支持的方式获得您的反馈。我就是这样做的:

  • 在 /app 文件夹中,我创建了一个 /languages 文件夹,其中包含每种语言的一个文件(english.php、spanish.php 等)
  • 每个文件都包含一系列在每个文件中具有相同名称的变量,其中包含要在视图中呈现的文本
  • 这些变量然后在不同的视图中回显
  • “语言”cookie 变量会在用户更改语言时更新
  • 在每个视图的控制器中,我包含一个格式如下的语言文件:

包括 $_SERVER['DOCUMENT_ROOT'] 。 “/应用程序/语言/”。 $_COOKIE["语言"] 。 ".php";

对我来说听起来很整洁。您对这种方法有什么负面想法吗?

【问题讨论】:

  • 不要在没有验证的情况下使用cookie值,客户端可以更改cookie!
  • 有几件事,您可能希望将语言作为 URL 的一部分。这样机器人就可以索引您的网站。此外,您可能希望将内容移动到数据库而不是将其保存在文件中,因为这样您添加新语言会更容易
  • 好点,感谢指出验证点!我正在考虑将其移至数据库。我最终认为通过文件可能会在性能方面更好......但确实可能更难维护。如果我通过 DB 选项,我正在考虑通过创建一个语言字段来设计它(我正在使用 mySQL),然后每页一个字段(index.php、home.php 等),每个字段都包含一个数组在每个页面上呈现的不同文本。你怎么看?
  • 你使用的是什么版本的 PHP?

标签: php performance model-view-controller localization internationalization


【解决方案1】:

当您使用 PHP 5.3.2 时,如果可以的话,我绝对建议您查看 intl 扩展。它充满了方便的函数和类来协助 i18n。例如,您可以使用以下 sn-p 从可用的语言中为您的访问者生成“最合适”的语言:

$langs = array('en', 'fr', 'de');
$preferences = Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']);
$locale = Locale::lookup($langs, $preferences);

除了直接逐字替换之外,还有更多需要考虑的事情。不同的语言有不同的格式约定。 Zend article 中有很多信息可能会很有用。

我的代码个人使用 XSL 进行模板化,当涉及到翻译时,我使用 XML 语言文件和 XPath 查询,以便模板可以直接理解语言文件,但 PHP 也可以使用 MessageFormatter 格式化字符串。

老实说,我会避免将数据库用作存储,只是为了提高性能。

【讨论】:

  • 信息量很大。 MessageFormatter 看起来对我来说真的很有趣,谢谢!
【解决方案2】:

您还可以解析接受语言标头以帮助决定做什么。

Accept-Language:en-GB,en-US;q=0.8,en;q=0.6

我的看起来是这样的。这不是万无一失的,但它可能是一种自动设置适当 cookie 的方法。

【讨论】:

  • 谢谢,同意这是确定相关默认语言的好方法,但您也希望让用户在应用程序中更改他们的语言(想想不使用自己电脑的旅行者) .
  • 完全正确——不过,这是一种以相当高的准确度猜测默认值的简单方法。
  • 离万无一失还有很长的路要走,大多数人无论语言如何都不会改变它。
  • 我对此了解不多,但它肯定会根据您的操作系统安装语言或浏览器的构建而改变吗?德语 Win 7 安装是否会将此更改为在所有浏览器中要求德语?
【解决方案3】:

只是一些想法

  • 如果您的每种语言都有一个文件,并且您的网站有多个页面,那么您很快就会忘记哪个标签包含哪个页面上的哪些文本
  • 如何确保在创建新标签时存在所有其他语言的标签并且它们已被翻译?
  • 如何处理不同语言的格式?浪漫语言往往比英语长约 30%,因此可能会破坏页面流量。
  • 同样,希伯来语是从右到左 (RTL) 而不是欧洲语言的 LTR?还是中文和日文的行流可能不同且没有空格?
  • 如何进行翻译?导出文件并再次导入?您是否打算使用 xliff 或 TMX 或 gettext 版本来使翻译人员的工作更轻松并降低翻译成本?
  • 您如何对翻译进行质量检查?

【讨论】:

    【解决方案4】:

    由于您只是在语言文件中有数据,我建议使用GetText。它是用于国际化的 C++ 标准 GetText 的一个端口,有大量工具可以构建语言文件,并且由于在运行时编译文件而非常快。

    您实际上是使用一种 INI 文件格式构建您的数据文件(例如 fr.poen.po)并将这些文件编译为专门的.mo 文件 (fr.mo, en.mo, ...) 并使用静态函数 _() 简单地回显国际化字符串,例如echo _("Hello World"); 将产生德语输出 Hallo Welt 或(如果 .mo 文件中没有可用的翻译)默认字符串 Hello World

    至于选择正确的语言:这取决于您的要求。正如已经指出的,您应该使用浏览器的Accept-language-Header,并且可能希望通过会话信息添加对覆盖的支持。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-18
      • 2011-01-30
      • 2017-06-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多