通过会话的多语言,两个目录

时间:2018-04-10 14:41:31

标签: php html session multiple-languages

所以我刚刚在我的新工作上开始进行web开发,这意味着我只有非常基本的php知识,我的html,css和js知识要好得多。 我正在尝试通过php会话构建一个基本的多语言网站,但我无法让它以我想要的方式工作。 我有一个index.php文件和另外两个名为EN和DE的文件夹,其中包含Englisch.html和Deutsch.html文件。 html文件只包含一些文本,我的目标是在我的站点顶部有两个按钮(或类似的),称为EN和DE,它们切换会话以包含所述文件夹中的文件并显示文本在按钮旁边并保持如果每种语言有多个文件,则每页上都有语言切换功能。默认情况下,我希望语言为英语,所以首先加载Englisch.html。 我猜我需要在检查会话的每个html文件上创建一个if else语句,如下所示:如果会话EN包含Englisch.html elseif会话DE包括Deutsch.html,并且在index.php上我需要设置会话的参数如下所示:startSession EN包括Englisch.html startSession DE include Deutsch.html? 我不知道我有多远和任何帮助,特别是实际的代码示例将不胜感激。我希望这足以说明我的问题。

2 个答案:

答案 0 :(得分:1)

从长远来看,你尝试过的解决方案会让你感到痛苦。

对于不同语言的不同文件之间切换似乎是一个简单的解决方案,但假设您的网站变得更加动态,而不是* .html文件要处理* .php文件,然后需要每个本地化文件中的逻辑相同。它不能很好地扩展。

我建议使用翻译库,有很多可用的,我在symfony's translation取得了很好的成功,你也可以包含在任何php项目中。

然后翻译成:

$translatedString = $translator->trans("My content");

然后可以在yaml文件中维护翻译,并根据语言环境选择正确的语言,每个未翻译的字符串将默认为英语。

现在,无论何时你的逻辑发生变化,它都只是在你需要调整它的地方。

答案 1 :(得分:0)

我同意K0pernikus,因为你的解决方案不能很好地扩展。您可以在一小时内自己编写一个简单的翻译库,然后您可以测试它以确定它是否足够强大以满足您的需求。

这个想法是拥有没有任何逻辑的语言文件。您只需调用所需的文件即可。关于您的库中包含哪种语言,文件,翻译密钥等的所有逻辑。

我会把它简单地保存到单个文件中;当然,实际的翻译也需要存储在文件中。

目录结构:

  • /locale/en/messages.php
  • /locale/fr/messages.php
  • /区域设置/../ messages.php
  • translator.php(这是主库文件,需要包含在每个页面上)

在每个messages.php文件中,您需要返回翻译密钥的数组及其各自的翻译。翻译键是您在视图中使用的键。对于大型应用程序,这些文件将变得很大,有数百或数千行。如果您打算保留这个自行开发的解决方案,则需要实现缓存。话虽这么说,我有几百个翻译的文件,并没有注意到任何重大的性能影响。

<?php
// en
return array(
    'applicationName' => 'My name is Dank',
    ...


<?php
// fr
return array(
    'applicationName' => 'je m\'appelle Dank',
    ...

接下来,您需要一个库来阅读这些翻译并将实际的翻译文本返回给您。这个文件可能只是一个辅助函数集合或一个完整的OOP类。为简单起见,这里有一组帮助完成工作的辅助方法。它没有实现参数化替换,您可以通过使t()接受第二个参数来相对容易地添加该功能,但这是另一个完全不同的主题。

这里的主要方法是t()。它非常简单,只接受一个翻译密钥。防爆。 applicationNamegreeting

警告 - 我去年匆匆写了这个逻辑,如果它不适合你就不会道歉。

首先,它尝试确定使用哪种语言。它按优先级顺序执行此操作:URL,会话,浏览器,后备。

  • 首先尝试通过查找从URL获取语言/区域设置 一个名为lang的查询字符串参数。如果你考虑一下,那就是 有意义,因为用户打算通过单击a切换他们的语言 链接说“英语”或“法语”。
  • 如果在网址中找不到,则继续检查一个 在会议中。同样,如果它在那里找到它,它就会使用它。
  • 如果它既没有在URL中也没有在会话中找到它,那么它会检查 来自请求的浏览器/标题。
  • 最后,如果在这3个地点中没有找到它,那么它就会落下 返回$defaultLanguage
  • 中指定的默认语言

找到一种语言后,它会将其放入会话中,因此下一个请求不需要再次执行。它还会根据发现的语言加载相应的messages.php文件。

最后,一旦找到语言并将正确的文件加载到内存中,它将搜索给定的$key并返回相应的翻译。如果找不到$key,那么它只会返回给定的$key,它将显示在您的视图中,这样您就会知道出现了可怕的错误,您需要开始调试。

<?php 
/**
 * Performs the actual translation based on the given key. This is the method that is used
 * in the actual views to translate a message.
 *
 * @param $key
 * @return mixed
 * @throws Exception
 */
function t($key)
{
    $language = getLanguage();

    $messages = require "{$_SERVER['DOCUMENT_ROOT']}/locale/{$language}/messages.php";

    return (array_key_exists($key, $messages))
        ? $messages[$key]
        : $key;
}

/**
 * Returns the language as defined by either the URL, session, or browser setting.
 * If a language could not be determined, or is not in a list of supported languages, the default
 * language passed in to this method will be returned.
 *
 * @param string $defaultLanguage
 * @return string
 */
function getLanguage($defaultLanguage = 'en')
{
    $language = null;

    if (isset($_REQUEST['lang'])) {
        $language = $_REQUEST['lang'];
    } elseif (isset($_SESSION['LANG'])) {
        $language = $_SESSION['LANG'];
    } else {
        $language = getLanguageFromBrowser('en');
    }

    // If the language given to us is not in our list of supported languages, use the default language.
    if (!isset($language) || !in_array($language, getSupportedLanguages())) {
        $language = $defaultLanguage;
    }

    // Store the current language to the session for future use.
    $_SESSION['LANG'] = $language;

    return $language;
}


/**
 * Returns the language that the client's browser is set to use. If we're unable to
 * determine a language from the browser this will return the default language passed
 * in.
 *
 * @param string $defaultLanguage
 * @return int|string
 */
function getLanguageFromBrowser($defaultLanguage = 'en')
{
    $languages = [];
    if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
        // break up string into pieces (languages and q factors)
        preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $lang_parse);

        if (count($lang_parse[1])) {
            // create a list like "en" => 0.8
            $languages = array_combine($lang_parse[1], $lang_parse[4]);

            // set default to 1 for any without q factor
            foreach ($languages as $lang => $val) {
                if ($val === '') $languages[$lang] = 1;
            }

            // sort list based on value
            arsort($languages, SORT_NUMERIC);
        }
    }

    $supportedLanguages = getSupportedLanguages();

    foreach ($languages as $locale => $weighting) {

        // We're dealing with locale: Ex. en-US
        if (preg_match("/[a-z]{2}-[A-Z]{2}/", $locale)) {
            $browserLanguage = substr($locale, 0, 2);
        } else {
            // Probably dealing with a language: Ex. en
            $browserLanguage = $locale;
        }

        if (in_array($browserLanguage, $supportedLanguages)) {
            return $browserLanguage;
        }
    }

    return $defaultLanguage;
}

/**
 * Returns an array of languages this web application supports.
 *
 * @return array
 */
function getSupportedLanguages()
{
    return [
        'en',
        'fr'
    ];
}

要使用它,请将这些方法保存到名为translator.php的文件中,然后在要使用翻译的每个页面中包含该文件。

样品:

<?php
session_start();
require_once('translator.php');

// Output your language switcheroo-gadget
if (getLanguage() === 'en') {
    echo '<a href="' . $_SERVER['PHP_SELF'] . '?lang=fr">French</a>';
} else {
    echo '<a href="' . $_SERVER['PHP_SELF'] . '?lang=en">English</a>';
}


// Your code... blah blah

// Ahh.. Finally, a translation!
echo '<h1>' . t('applicationName') . '</h1>';

修改

我要说的最后一件事是,你可以了解到本地化,国际化(通常缩写为i18n)的整个世界。

在我的例子中,我简单地称它为语言,但通常人们将其称为语言环境,但它具有不同的含义和语法。例如,en_CA和en_US和en_GB之间存在差异;所有这些都是英语但有区域差异。

echo t('salutation');