举例说明常见的翻译: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. WCF 下的windows服务的安装卸载

    安装:启动vs2010(如果是win2008要以管理员来启动)命令:installutil demo.exe 卸载:先在服务里停止这个服务,然后启动vs2010(如果是win2008要以管理员来启动) ...

  2. bugumongo--ConnectToMongoDB

    连接MongoDB 在能够对MongDB进行操作之前,需要使用BuguConnection连接到MongoDB数据库.代码如下: BuguConnection conn = BuguConnectio ...

  3. C# CLR及程序集部署浅析

    摘 要 .NET Framework 到底是什么?公共语言运行时和 .NET Framework 类库分别指的是什么东西?CLR. CLS. CTS.FCL等这些又是什么?为什么出现程序集的概念?它与 ...

  4. C#.Net 如何动态加载与卸载程序集(.dll或者.exe)4-----Net下的AppDomain编程 [摘录]

    最近在对AppDomain编程时遇到了一个问题,卸载AppDomain后,在内存中还保留它加载的DLL的数据,所以即使卸载掉AppDomain,还是无法更新它加载的DLL.看来只有关闭整个进程来更新D ...

  5. 【HDOJ】1448 The Treasure

    这就是个简单的bfs.真没什么好说的,三维的状态就可以了.每次预处理一下monster的位置,然后再恢复. /* 1924 */ #include <iostream> #include ...

  6. windows编译 obs-studio

    github下载源码 https://github.com/jp9000/obs-studio 还需要一个开发包 http://code.fosshub.com/OBS/download/depend ...

  7. 1106. Two Teams(dfs 染色)

    1106 结点染色 当前结点染为黑 朋友染为白  依次染下去 这题是为二分图打基础吧 #include <iostream> #include<cstdio> #include ...

  8. bzoj1532

    就题目而言,这道题是裸的二分+最大流 但是这样是TLE的,我们考虑优化 1. 我们可以先贪心,这样二分的上界就可以缩小了 2. 最大流我们可以不急着跑增广路,我们可以先贪心一个流然后再跑增广路 但是我 ...

  9. php对提交数据的验证

    <?php //security.php /** * @author zhengwei * @copyright 2007 */ /* 函数名称:inject_check() 函数作用:检测提交 ...

  10. 设计模式Day01

    一.工厂模式 1.工厂模式的关键点就是如何描述好这两个角色之间的关系,分为四种情况: (1)单一产品系,工厂生产一种类型的产品: (2)多产品系,特征相同.工厂生产多种类型的产品: (3)多产品系,部 ...