举例说明常见的翻译:Yii::t('app','Login');
追踪源码:BaseYii.php 文件 ,Yii::t($category, $message, $params = [], $language = null) 这个方法实际上是 \yii\i18n\I18N::translate()的一个捷径方法
  /**
* Translates a message to the specified language.
*
* This is a shortcut method of [[\yii\i18n\I18N::translate()]].
*
* The translation will be conducted according to the message category and the target language will be used.
*
* You can add parameters to a translation message that will be substituted(取代) with the corresponding(相应的) value after
* translation. The format for this is to use curly brackets around the parameter name as you can see in the following example:
*
* ```php
* $username = 'Alexander';
* echo \Yii::t('app', 'Hello, {username}!', ['username' => $username]);
* ```
*
* Further formatting of message parameters is supported using the [PHP intl extensions](http://www.php.net/manual/en/intro.intl.php)
* message formatter. See [[\yii\i18n\I18N::translate()]] for more details.
*
* @param string $category the message category.
* @param string $message the message to be translated.
* @param array $params the parameters that will be used to replace the corresponding placeholders in the message.
* @param string $language the language code (e.g. `en-US`, `en`). If this is null, the current
* [[\yii\base\Application::language|application language]] will be used.
* @return string the translated message.
*/
public static function t($category, $message, $params = [], $language = null)
{
if (static::$app !== null) {
return static::$app->getI18n()->translate($category, $message, $params, $language ?: static::$app->language);
} else {
$p = [];
foreach ((array) $params as $name => $value) {
$p['{' . $name . '}'] = $value;
} return ($p === []) ? $message : strtr($message, $p);
}
}

查看 \yii\i18n\I18N::translate()方法:

 /**
* Translates a message to the specified language.
*
* After translation the message will be formatted using [[MessageFormatter]] if it contains
* ICU message format and `$params` are not empty.
*
* @param string $category the message category.
* @param string $message the message to be translated.
* @param array $params the parameters that will be used to replace the corresponding placeholders in the message.
* @param string $language the language code (e.g. `en-US`, `en`).
* @return string the translated and formatted message.
*/
public function translate($category, $message, $params, $language)
{
// 返回MessageSource the message source for the given category.
$messageSource = $this->getMessageSource($category);
//返回翻译的内容
$translation = $messageSource->translate($category, $message, $language);
//格式话翻译的内容
if ($translation === false) {
return $this->format($message, $params, $messageSource->sourceLanguage);
} else {
return $this->format($translation, $params, $language);
}
}

其中 $messageSource = $this->getMessageSource($category);//根据配置文件内容和 给的参数$category 返回继承MessageSource 相应子类的实例对象, 本例根据配置文件返回PhpMessageSource对象

 <?php
return [
'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
'components' => [
'cache' => [
'class' => 'yii\caching\FileCache',
],
'i18n'=>[
'translations' => [
'app*'=> [
'class' => 'yii\i18n\PhpMessageSource',
'basePath'=>'@common/messages',
'fileMap'=>[
'app'=>'app.php',
],
],
],
],
],
];

$messageSource = $this->getMessageSource($category); 返回继承MessageSource 相应子类的实例对象

  /**
* Returns the message source for the given category.
* @param string $category the category name.
* @return MessageSource the message source for the given category.
* @throws InvalidConfigException if there is no message source available for the specified category.
*/
//根据配置文件内容和 给的参数$category 返回继承MessageSource 相应子类的实例对象, 本例根据配置文件返回PhpMessageSource对象
public function getMessageSource($category)
{
if (isset($this->translations[$category])) {
$source = $this->translations[$category];
if ($source instanceof MessageSource) {
return $source;
} else {
return $this->translations[$category] = Yii::createObject($source);
}
} else {
// try wildcard matching
foreach ($this->translations as $pattern => $source) {
if (strpos($pattern, '*') > 0 && strpos($category, rtrim($pattern, '*')) === 0) {
if ($source instanceof MessageSource) {
return $source;
} else {
return $this->translations[$category] = $this->translations[$pattern] = Yii::createObject($source);
}
}
}
// match '*' in the last
if (isset($this->translations['*'])) {
$source = $this->translations['*'];
if ($source instanceof MessageSource) {
return $source;
} else {
return $this->translations[$category] = $this->translations['*'] = Yii::createObject($source);
}
}
} throw new InvalidConfigException("Unable to locate message source for category '$category'.");
}

再根据实例对象的translate方法返回翻译的内容,  $translation = $messageSource->translate($category, $message, $language);

MessageSource  类的 translate方法如下:

   /**
* Translates a message to the specified language.
*
* Note that unless [[forceTranslation]] is true, if the target language
* is the same as the [[sourceLanguage|source language]], the message
* will NOT be translated.
*
* If a translation is not found, a [[EVENT_MISSING_TRANSLATION|missingTranslation]] event will be triggered.
*
* @param string $category the message category
* @param string $message the message to be translated
* @param string $language the target language
* @return string|boolean the translated message or false if translation wasn't found or isn't required
*/
// 翻译一段信息为指定的语言文件下的内容
public function translate($category, $message, $language)
{
if ($this->forceTranslation || $language !== $this->sourceLanguage) { return $this->translateMessage($category, $message, $language);
} else {
return false;
}
}

$this->translateMessage($category, $message, $language);
  /**
* Translates the specified message.
* If the message is not found, a [[EVENT_MISSING_TRANSLATION|missingTranslation]] event will be triggered.
* If there is an event handler, it may provide a [[MissingTranslationEvent::$translatedMessage|fallback translation]].
* If no fallback translation is provided this method will return `false`.
* @param string $category the category that the message belongs to.
* @param string $message the message to be translated.
* @param string $language the target language.
* @return string|boolean the translated message or false if translation wasn't found.
*/
protected function translateMessage($category, $message, $language)
{
$key = $language . '/' . $category;
if (!isset($this->_messages[$key])) {
// $language = 'zh-CN' $category = 'app'
// $this->loadMessages($category, $language) 为合并后的指定类别语言的翻译数组 key => value
$this->_messages[$key] = $this->loadMessages($category, $language);
}
if (isset($this->_messages[$key][$message]) && $this->_messages[$key][$message] !== '') {
return $this->_messages[$key][$message];
} elseif ($this->hasEventHandlers(self::EVENT_MISSING_TRANSLATION)) {
$event = new MissingTranslationEvent([
'category' => $category,
'message' => $message,
'language' => $language,
]);
$this->trigger(self::EVENT_MISSING_TRANSLATION, $event);
if ($event->translatedMessage !== null) {
return $this->_messages[$key][$message] = $event->translatedMessage;
}
} return $this->_messages[$key][$message] = false;
}
根据配置文件生成的 MessageSource子类相应对象的loadMessages方法,生成翻译的文件数组内容,在根据内容查找相应的以$message为键的对应值:
return $this->_messages[$key][$message];
本例根据PhpMessageSource对象的translateMessage方法为例说明:
   /**
* Loads the message translation for the specified $language and $category.
* If translation for specific locale code such as `en-US` isn't found it
* tries more generic `en`. When both are present, the `en-US` messages will be merged
* over `en`. See [[loadFallbackMessages]] for details.
* If the $language is less specific than [[sourceLanguage]], the method will try to
* load the messages for [[sourceLanguage]]. For example: [[sourceLanguage]] is `en-GB`,
* $language is `en`. The method will load the messages for `en` and merge them over `en-GB`.
*
* @param string $category the message category
* @param string $language the target language
* @return array the loaded messages. The keys are original messages, and the values are the translated messages.
* @see loadFallbackMessages
* @see sourceLanguage
*/
protected function loadMessages($category, $language)
{
//返回指定类别和语言的文件路径
$messageFile = $this->getMessageFilePath($category, $language);
// 根据文件路径,加载翻译文件,为数组键值对
$messages = $this->loadMessagesFromFile($messageFile); $fallbackLanguage = substr($language, 0, 2);
$fallbackSourceLanguage = substr($this->sourceLanguage, 0, 2); if ($language !== $fallbackLanguage) {
// $language = 'zh-CN' $fallbackLanguage = 'zh' 合并语言zh-CN和zh文件为新的$messages
$messages = $this->loadFallbackMessages($category, $fallbackLanguage, $messages, $messageFile);
} elseif ($language === $fallbackSourceLanguage) {
// $language = 'zh' $fallbackLanguage = 'zh' $this->sourceLanguage = 'en' 合并zh 文件和en 文件,当zh文件翻译key的value信息没有时用 en 文件的相应的value 替代,合并为新的翻译数组内容 $messages
$messages = $this->loadFallbackMessages($category, $this->sourceLanguage, $messages, $messageFile);
} else {
if ($messages === null) {
Yii::error("The message file for category '$category' does not exist: $messageFile", __METHOD__);
}
} return (array) $messages;
}
 //返回指定类别和语言的文件路径
$messageFile = $this->getMessageFilePath($category, $language);
  /**
* Returns message file path for the specified language and category.
*
* @param string $category the message category
* @param string $language the target language
* @return string path to message file
*/
//返回指定的语言和类别文件路径
protected function getMessageFilePath($category, $language)
{
//语言类别文件路径
$messageFile = Yii::getAlias($this->basePath) . "/$language/";
if (isset($this->fileMap[$category])) {
$messageFile .= $this->fileMap[$category];
} else {
$messageFile .= str_replace('\\', '/', $category) . '.php';
} return $messageFile;
}
// 根据文件路径,加载翻译文件,为数组键值对
$messages = $this->loadMessagesFromFile($messageFile);
  /**
* Loads the message translation for the specified language and category or returns null if file doesn't exist.
*
* @param string $messageFile path to message file
* @return array|null array of messages or null if file not found
*/
//加载翻译文件,翻译文件为数组文件
protected function loadMessagesFromFile($messageFile)
{
if (is_file($messageFile)) {
$messages = include($messageFile);
if (!is_array($messages)) {
$messages = [];
} return $messages;
} else {
return null;
}
}
//根据不同的条件,从其他文件中补充语言文件的缺少的key 的值value 
$messages = $this->loadFallbackMessages($category, $this->sourceLanguage, $messages, $messageFile);
 /**
* The method is normally called by [[loadMessages]] to load the fallback messages for the language.
* Method tries to load the $category messages for the $fallbackLanguage and adds them to the $messages array.
*
* @param string $category the message category
* @param string $fallbackLanguage the target fallback language
* @param array $messages the array of previously loaded translation messages.
* The keys are original messages, and the values are the translated messages.
* @param string $originalMessageFile the path to the file with messages. Used to log an error message
* in case when no translations were found.
* @return array the loaded messages. The keys are original messages, and the values are the translated messages.
* @since 2.0.7
*/
protected function loadFallbackMessages($category, $fallbackLanguage, $messages, $originalMessageFile)
{
// 返回的信息文件路径
$fallbackMessageFile = $this->getMessageFilePath($category, $fallbackLanguage);
//根据文件路径信息,加载文件的内容
$fallbackMessages = $this->loadMessagesFromFile($fallbackMessageFile); if (
$messages === null && $fallbackMessages === null
&& $fallbackLanguage !== $this->sourceLanguage
&& $fallbackLanguage !== substr($this->sourceLanguage, 0, 2)
) {
Yii::error("The message file for category '$category' does not exist: $originalMessageFile "
. "Fallback file does not exist as well: $fallbackMessageFile", __METHOD__);
} elseif (empty($messages)) {
return $fallbackMessages;
} elseif (!empty($fallbackMessages)) {
// 当$message数组key 值为空时,且$fallbackMessages对应的key的翻译内容存在是,把$fallbackMessages的内容翻译数组赋值给 $messages[$key]
foreach ($fallbackMessages as $key => $value) {
if (!empty($value) && empty($messages[$key])) {
$messages[$key] = $fallbackMessages[$key];
}
}
} return (array) $messages;
}
最后返回$messages:
return (array) $messages;

根据提供的参数($message)把$message作为key 查找 $messages 数组中对应的key的值

yii2 i18n学习的更多相关文章

  1. 国际化(i18n)学习

    一 软件的国际化:软件开发时,要使它能同时应对世界不同地区和国家的访问,并针对不同地区和国家的访问,提供相应的.符合来访者阅读习惯的页面或数据. 国际化(internationalization)又称 ...

  2. yii2框架学习笔记

    1.去掉yii2模版默认的头部和脚部的两种方法: (1) 第一种 $this->layout = false; $this->render('index'); (2) 第二种(partia ...

  3. Yii2.0学习笔记:创建登录表单

    第一步:在model层创建一个EntryForm.php文件 复制以下代码,注意model的文件.方法.类的命名规范(大小写) <?php namespace app\models; use Y ...

  4. Yii2.0学习笔记:第一个页面Saying Hello

    Controller目录下创建TestController.php 复制下面代码,yii跟tp一样,全程命名空间 <?php namespace app\controllers; use yii ...

  5. Yii2 基础学习

    <?php //url创建 echo Url::to(''); // same controller, different action // /index.php?r=management/d ...

  6. YII2.O学习三 前后台用户数据表分离

    之前我们完成了Advanced 模板安装,也完成了安装adminlte 后台模板,这一步是针对前端和后台用户使用不同的数据库表来管理,做到前后台用户分离的效果: 复制一张user数据表并重命名为adm ...

  7. YII2.0学习二 安装adminlte 后台模板

    控制台切换到安装目录wwwroot/shanghai/ 修改一下composer镜像地址:composer 使用中国镜像 运行 composer require dmstr/yii2-adminlte ...

  8. YII2.0学习一 Advanced 模板安装

    下载github上的完事安装包(本机环境使用Composer安装非常慢) https://github.com/yiisoft/yii2-app-advanced 解压到文件目录 wwwroot/sh ...

  9. Yii2.0学习--目录结构

    目录结构: 创建一个控制器: <?php /** * Created by Haima. * Author:Haima * QQ:228654416 * Date: 2018/8/23 * Ti ...

随机推荐

  1. 在服务器端使用 Git 创建源代码仓库

    下面简单讲述在服务器搭建 Git 仓库的过程. 安装 Git 程序 Git 是分布式的,即程序不区分服务端和客户端,大部分 Linux 发行版的官方源里都有它,比如在 Archlinux 里安装 Gi ...

  2. The document has been modified outside of Code Composer. Would you like to reload the file

    2013-06-20 10:03:32 烧写过程是合众达给出的文档 problem: I'm new to using Code Composer Studio 3.3 and am having a ...

  3. Maximum Allowed Error 7 错误解决

    http://blog.csdn.net/lyx123/article/details/6238167 这段时间,一直在做WINCE 的应用,后来将NK做大后,必须修改EBOOT,以便能够提供较大的空 ...

  4. VS2005工程增加SDK

    客户最近发过来一个VS2005的工程,此工程是基于Pocket PC 2003(ARMV4),需要改为我们WINCE6.0系统对应的SDK,下面具体说明如何添加新的SDK. 选择configurati ...

  5. git同步远端的分支

    如果用命令行,运行 git fetch,可以将远程分支信息获取到本地, 再运行 git checkout -b local-branchname origin/remote_branchname  就 ...

  6. poj 3393 Lucky and Good Months by Gregorian Calendar(模拟)

    题目:http://poj.org/problem?id=3393一道题目挺长的模拟题,参考了网上大神的题解. #include <iostream> #include <cstdi ...

  7. Datalist增删改查——联系人管理

    关于Datalist,其实和Repeater差不多,都是存放数据的控件,相比较下,Datalist和Repeater虽然都是用的模板,但是Datalist比之多了Edit模板,也就是编辑栏的模板,事件 ...

  8. 对DataTable里数据进行排序

    在日常开发过程中,有一个DataTable集合,里面有很多字段,现在要求针对某一列进行排序,如果该列为数字的话,进行ASC即可实现,但是该字段类型为string,此时排序就有点不正确了. 我也不多废话 ...

  9. (转载)Let's Play Games!

    第1题  Alice和她的同学Bob通过网上聊天商量明天早晨谁去教室打扫卫生的事,Bob说:“我在桌上放了一枚硬币,你猜一下,是正面朝上还是反面朝上?如果猜对了,我去扫地.如果猜错了,嘿嘿….” Al ...

  10. FirstOrDefault

    FirstOrDefault:取序列中满足条件的第一个元素,如果没有元素满足条件,则返回默认值(对于可以为null的对象,默认值为null,对于不能为null的对象,如int,默认值为0)