【问题标题】:The best way to implement multi-language PHP实现多语言 PHP 的最佳方式
【发布时间】:2011-09-26 18:07:11
【问题描述】:

首先,我知道有很多关于多语言功能的答案,我没有找到我想要的答案。

我想了三种我可以使用的方法。每次向 Web 表单界面添加新值时,我都需要使用 PHP 创建语言文件。

前两个有点相似 - 在特定语言文件中使用数组或定义,并在运行开始时包含它。 但在这种情况下,我可能会加载数千个定义或数组,只是为了在每个页面中使用一些。

第三种方法是创建每次使用关键字或完整短语调用的函数,并使用IF-s 或switch 选择正确的术语(或如果不匹配则返回调用的键)。

最好的方法是什么? 我决定做一些测试。我尝试了三种不同的方法并测量了它所花费的时间和内存:

  1. 我定义了一个数组(22 个值)并在其上运行 1 到 1,000,000 - 检查调用值 - 三个中的一个,使用 % 运算符选择要使用的内容并将其设置在变量上

    • 耗时:0.476591110229 秒
    • 内存:6536 字节
  2. 我使用了相同的数组(22 个值)并使用函数 - return $arr[$string]; 调用它(只是为了方便的工作方式以及在需要时将其更改为不同方式的能力)

    • 耗时:0.960635185242 秒
    • 内存:6704 字节
  3. 我创建了一个带有字符串列表的函数并使用switch-->case 我选择了返回字符串

    • 耗时:1.46953487396 秒
    • 内存:848 字节

好吧,现在的问题是什么是正确的选择——更喜欢时间还是更喜欢记忆。

如果网站很大并且会占用大量内存 - 我无法更改它,因为它是用数组构建的 - 如果它与函数一起使用,我总是可以更改它。

【问题讨论】:

标签: php


【解决方案1】:

在代码方面,这样的东西对你来说会很棒。它必须基于用户的选择(从按钮或菜单中选择一种语言)或基于浏览语言(这不是最好的方法)。

index.php

<?php

// verify the user's choice
if ($_POST[lang] == "en") 
{
    include_once("en_language.php");
}

if ($_POST[lang] == "pt") 
{
    include_once("pt_language.php");
}

// calling a lable in your page
echo LABEL_MENU;


// the rest of your file
...
?>

en_language.php

<?php
// ENGISH Language file
define('LABEL_MENU','Main Menu');

// the whole file with the labels of your system

?>

pt_language.php

<?php
// PORTUGUESE Language file
define('LABEL_MENU','Menu Principal');

// the whole file with the labels of your system

?>

补充

如果你希望使用数组类型而不是常量值与define(),但我不确定什么比...更快。

$arrays = array("MAIN_MENU" => "Main Menu", "LEFT_MENU" => "Left Menu"); 
echo $arrays["MAIN_MENU"];

【讨论】:

  • 正如我所说 - 我想过(或使用数组),但仍然 - 我可以定义很多我根本不会使用的字符串,并且当网站获得大量访问时变得有点沉重(我认为)
  • @Joe Polico - 太好了,这是最简单的方法。
  • 但我正在寻找两者 - 最简单的方法和最快的方法(对于服务器)。确实,为了简便起见,最好使用管理所有语言字符串的函数
  • 我认为在这种方式上没有什么比您要寻找的更容易了,也许您最好选择使用 ZEND 之类的框架或您喜欢的任何风格的 php 框架,因为它们都处理以下语言它工作的基础。但我会告诉你,这并不容易,尤其是如果你以前从未使用过框架。
  • 我不认为我可以开始改变我所有的工作方式来使用某些框架。但是你能告诉我两者哪个更好 - 使用switch->case 结构或使用数组/定义创建函数?
【解决方案2】:

将您的字符串分成类别 - 一个是全局的,另一个是与您在网站中的视图相对应的类别(例如 lang_global、lang_profile、lang_something_else) 包括全局文件和当前视图对应的文件。通过这种方式,您不会加载整个翻译,而只会加载其中的一个子集。而且它更易于管理,您可以提供上下文,对同一字符串进行不同的翻译。

【讨论】:

  • 我需要它用于 CMS - 将它分成多个部分有点问题 - 系统可以在每个站点上更改,并且可以从任何地方调用语言字符串.. 它太复杂了每当我想调用它们时,函数/文件中每个字符串的位置
  • 您在 CMS 中仍有实体。实体可以有单独的语言文件。每个模块/插件也可以有一个语言文件。
  • 使用起来仍然很复杂..系统只是基础,需要在每个网站上进行更改,尝试定义每次放置当前字符串的位置并不是那么简单的工作方式
  • 然后放入数据库。创建动态缓存——当前页面使用的所有字符串,按字符串、翻译、页面路径记录,等后续请求通过页面路径(索引字段)查询并获取翻译,而不是按字符串调用字符串...
  • 如果我有一个字符串出现在我画廊的每个类别中?它可能有多个路径
【解决方案3】:

这里有一些有用的答案,但如果您使用 composer 作为依赖项管理器,我也会推荐 symfony/translation

lang/messages.fr.yaml:

Hello, %name%!: Bonjour, %name%!
Goodbye: Goodbye!

lang/messages.en.yaml:

Hello, %name%!: Hello, %name%!

文件.php:

<?php
use Symfony\Component\Translation\Translator;
use Symfony\Component\Translation\Translator\Loader\YamlFileLoader;

require_once __DIR__ . '/vendor/autoload.php';

$translator = new Translator();

$translator->addLoader('yaml', new YamlFileLoader());
$translator->addResource('yaml', __DIR__ . 'lang/messages.en.yaml', 'en');
$translator->addResource('yaml', __DIR__ . 'lang/messages.fr.yaml', 'fr');

$translator->setFallbackLocales(array('en'));

$translator->setLocale('en');

echo $translator->translate('Hello, %name%!', ['name' => 'saif']); // Hello, saif!

$translator->setLocale('fr');

echo $translator->translate('Hello, %name%!', ['name' => 'saif']); // Bonjour, saif!
// Goodbye isn't set in the "fr" file, translator uses the fallback locale instead
echo $translator->translate('Goodbye'); // Goodbye !

阅读更多关于如何使用 symfony 翻译组件here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 2016-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多