通过会话提供多种语言,两个目录 [英] multiple language via session, two directories

查看:81
本文介绍了通过会话提供多种语言,两个目录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我刚刚开始新工作的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 include Englisch.html startSession DE include Deutsch.html? 我不知道我还有多远,任何帮助,特别是实际的代码示例,将不胜感激.我希望这能足够准确地描述我的问题.

So I just started web development on my new job, meaning I only have very basic knowledge of php, my html, css and js knowledge is a lot better. I'm trying to build a basic multiple language site via php sessions but I just can't get it to work the way I want. I have an index.php file and two more folders called EN and DE in which I have the Englisch.html and the Deutsch.html file. The html files only contain some text and it's my goal to have two buttons (or similar) at the top of my site called EN and DE which switch the session to include the files in said folders and display the text beneeth the buttons and keep the language switch function on every page if I had more then one file per language. By default I want the language to be english so load the Englisch.html first. I'm guessing I need to create an if else statement on every html file that checks the session so something like: if session EN include Englisch.html elseif session DE include Deutsch.html, and on the index.php I somehow need to set the parameters for the session so something like: startSession EN include Englisch.html startSession DE include Deutsch.html ? I have no idea how far off I am and any help, espacially actual code examples would be greatly appreciated. I hope this described my problem precisely enough.

推荐答案

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

I agree with K0pernikus in that your solution won't scale well. You can write a simple translation library yourself in under an hour and you can then test it to see if it will be robust enough for your needs.

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

The idea is to have language files without any logic in them. You simply call the file you need. All the logic about which language, file, translation key etc. is contained in your library.

我将使其非常简单,并简化为单个文件;当然,每个实际的翻译也都需要存储在一个文件中.

I'll keep it very simple and down to a single file; of course, the actual translations will each need to be stored in a file too.

目录结构:

  • /locale/en/messages.php
  • /locale/fr/messages.php
  • translator.php (这是主库文件,需要包含在每个页面中)
  • /locale/en/messages.php
  • /locale/fr/messages.php
  • translator.php (this is the main library file and needs to be included on every page)

在每个messages.php文件中,您需要返回一组翻译键及其各自的翻译.翻译键是您将在视图中使用的键.对于较大的应用程序,这些文件将变得很大,其中包含数百行或数千行.如果您打算保留此本地解决方案,则需要实施缓存.话虽这么说,我有数百个翻译的文件,并且没有发现任何明显的性能下降.

Within each messages.php file you need to return an array of translation keys and their respective translation. The translation keys are what you will use in your views. These files will become large with many hundreds or thousands of lines for larger applications. If you intend to keep this home-grown solution you'll need to implement caching. That being said, I have files with hundreds of translations and don't notice any significant performance hit.

<?php
// en
return array(
    'applicationName' => 'Matt\'s Marvelous Mysteries',
    ...


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

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

Next, you need a library to read these translations and return the actual translation text to you. This file could simply be a collection of helper functions or a full-blown OOP system. For simplicity, here is a collection of helper methods that get the job done. It does not implement parameterized substitution and you can add that feature relatively easily by making t() accept a 2nd argument, but that is a whole different topic for another time.

此处的主要方法是t().它非常简单,并接受一个翻译键.前任. applicationNamegreeting.

The main method in here is t(). It is very simple and accepts a single translation key. Ex. applicationName or greeting.

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

Firstly, it tries to determine which language to use. It does this in a sequence of priority: URL, session, browser, fallback.

  • 它首先尝试通过查找URL来获取语言/语言环境 一个名为lang的查询字符串参数.如果您考虑一下,那是有道理的,因为用户打算通过单击 英语"或法语"的链接.
  • 如果在URL中找不到一个,则继续检查一个 在会议中.再次,如果找到了它,它将使用它.
  • 如果它既不在URL中也不在会话中找到它,则它将检查 请求中的浏览器/标题.
  • 最后,如果在这3个位置中均未找到它,它就会掉落 回到$defaultLanguage中指定的默认语言.
  • It first tries to get the language/locale from the URL by looking for a query string parameter named lang. If you think about it, that makes sense because a user intends to switch their language by clicking a link that says "English" or "French".
  • If it doesn't find one in the URL it then moves on to check for one in the session. Again, if it finds it there it uses it.
  • If it finds it neither in the URL nor the session, then it checks the browser/headers from the request.
  • Finally, if it isn't found in any of those 3 locations then it falls back to the default language as specified in $defaultLanguage.

一旦找到一种语言,它将把它放入会话中,因此下一个请求不需要再次经历所有这些.它还根据发现的语言加载适当的messages.php文件.

Once a language has been found, it puts it into the session so the next request doesn't need to go through all that again. It also loads the appropriate messages.php file based on the discovered language.

最后,一旦找到语言并将正确的文件加载到内存中,它将搜索给定的$key并返回适当的翻译.如果未找到$key,则仅返回给定的$key,该$key将出现在您的视图中,因此您知道某些地方出了问题,您需要开始调试.

Finally, once the language has been found and right file has been loaded into memory it searches for the given $key and returns the appropriate translation. If the $key is not found then it simply returns the given $key which will show up in your views so you know something went horribly wrong and you need to start debugging.

<?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的文件中,然后将该文件包含在要使用翻译的每个页面中.

To use it, save these methods into a file called translator.php and then include that file in every page you want to use translations.

示例:

<?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).

The last thing I will say is that there is a whole world out there of localization, internationalization (often abbreviated as i18n) which you can learn about.

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

In my example, I simplistically called it language but often people referer to it as locale but that has a different meaning and syntax. For example, there is a difference between en_CA and en_US and en_GB; all of which are English but have regional differences.

echo t('salutation');

这篇关于通过会话提供多种语言,两个目录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆