代码之家  ›  专栏  ›  技术社区  ›  joko

通过会话、两个目录使用多种语言

  •  0
  • joko  · 技术社区  · 6 年前

    所以我刚开始在新工作中进行web开发,这意味着我只有非常基本的php知识,我的html、css和js知识要好得多。 我正试图通过php会话构建一个基本的多语言网站,但我就是不能让它按我想要的方式工作。 我有一个索引。php文件和另外两个名为EN和DE的文件夹,其中包含英语。html和德语。html文件。html文件只包含一些文本,我的目标是在我的网站顶部有两个按钮(或类似按钮),分别称为EN和DE,它们切换会话以将文件包含在所述文件夹中,并显示文本。如果我的每种语言有多个文件,则这些按钮将在每个页面上保留语言切换功能。默认情况下,我希望语言为英语,因此加载英语。html优先。 我猜我需要在每个html文件上创建一个if-else语句来检查会话,例如:if session EN包含English。html elseif会话DE包括德语。html和索引上的。php我需要为会话设置一些参数,比如:startSession EN include Englisch。html startSession DE包括Deutsch。html? 我不知道我离这里有多远,如果有任何帮助,尤其是实际的代码示例,我将不胜感激。我希望这足够准确地描述了我的问题。

    2 回复  |  直到 6 年前
        1
  •  1
  •   k0pernikus    6 年前

    从长远来看,你尝试的解决方案会对你不利。

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

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

    然后翻译变成:

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

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

    现在,每当你的逻辑发生变化时,你只需要在一个地方进行调整。

        2
  •  0
  •   waterloomatt    5 年前

    我同意K0pernikus的观点,因为您的解决方案无法很好地扩展。您可以在不到一个小时的时间内自己编写一个简单的翻译库,然后对其进行测试,看看它是否能够满足您的需要。

    想法是让语言文件中没有任何逻辑。您只需调用所需的文件。库中包含关于哪种语言、文件、翻译键等的所有逻辑。

    我将保持它非常简单,并简化为一个文件;当然,实际的翻译也需要存储在一个文件中。

    目录结构:

    • /语言环境/英语/消息。php
    • /语言环境/fr/消息。php
    • 翻译php (这是主库文件,需要包含在每页中)

    在每个 messages.php 需要返回数组的文件 翻译键 以及他们各自的翻译。转换键是您将在视图中使用的键。对于更大的应用程序,这些文件将变得更大,有数百或数千行。如果您打算保留这个自主开发的解决方案,则需要实现缓存。尽管如此,我有数百个翻译的文件,没有注意到任何显著的性能下降。

    <?php
    // en
    return array(
        'applicationName' => 'Matt\'s Marvelous Mysteries',
        ...
    
    
    <?php
    // fr
    return array(
        'applicationName' => 'Les merveilleux mystères de Matt',
        ...
    

    接下来,您需要一个库来阅读这些翻译并将实际的翻译文本返回给您。该文件可以是助手函数的集合,也可以是成熟的OOP系统。 为了简单起见,下面是一组帮助器方法,可以完成工作。它不实现参数化替换,您可以通过 t() 接受第二个论点,但这是另一次完全不同的话题。

    这里的主要方法是 t() 。它非常简单,可以接受单个 翻译键 .例如。 applicationName greeting

    首先,它试图确定使用哪种语言。它按优先级顺序执行:URL、会话、浏览器、回退。

    • 它首先尝试通过查找 名为的查询字符串参数 lang 。如果你仔细想想,这是有道理的,因为用户打算通过单击 链接显示“英语”或“法语”。
    • 如果在URL中找不到,则继续检查 在会话中。同样,如果它在那里找到它,它就会使用它。
    • 如果它在URL或会话中都没有找到它,那么它会检查 请求的浏览器/标题。
    • 最后,如果在这三个位置中的任何一个都没有找到它,那么它就会掉下来 返回中指定的默认语言 $defaultLanguage

    一旦找到一种语言,它就会将其放入会话中,这样下一个请求就不需要再次进行所有这些操作。它还加载适当的 消息。php 基于发现的语言的文件。

    最后,一旦找到语言并将正确的文件加载到内存中,它就会搜索给定的 $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($_GET['lang'])) {
            $language = $_GET['lang'];
        } elseif (isset($_SESSION['LANG'])) {
            $language = $_SESSION['LANG'];
        } else {
            $language = getLanguageFromBrowser($defaultLanguage);
        }
    
        // 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\u CA与en\u US和en\u GB之间存在差异;他们都是英语,但有地区差异。

    echo t('salutation');