Yii 2 高级项目模板,国际化的消息翻译服务的 Bug (当目标语言为美国英语,文件映射的类别名为:app 时,未被映射到 PHP 文件 @app/messages/en-US/app.php) 的分析解决
1、i18n 应用组件的配置代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 'components' => [ 'i18n' => [ 'translations' => [ 'model/*' => [ 'class' => 'yii\i18n\PhpMessageSource' , 'forceTranslation' => true, 'basePath' => '@common/messages' , ], '*' => [ 'class' => 'yii\i18n\PhpMessageSource' , 'forceTranslation' => true, 'basePath' => '@app/messages' , 'fileMap' => [ 'app' => 'app.php' , 'error' => 'error.php' , 'success' => 'success.php' , ], ], ], ], ], |
2、在 Postman 中请求接口,Headers 中,Accept-Language:zh-CN,当目标语言为简体中文,文件映射的类别名为:success 时,被映射到 PHP 文件 @app/messages/zh-CN/success.php,如图1
1 | return [ 'code' => 10000, 'message' => Yii::t( 'success' , '127016' ), 'data' => [ 'items' => array_values ( $models )]]; |
3、在 Postman 中请求接口,Headers 中,Accept-Language:zh-CN,当目标语言为简体中文,文件映射的类别名为:app 时,被映射到 PHP 文件 @app/messages/zh-CN/app.php,如图2
1 | $planLog ->opinion = Yii::t( 'app' , Yii::t( 'app' , Yii::t( 'app' , 302016), [ 'accepted_group_name' => $acceptedGroupName , 'accepted_user_nick' => $identity ->user_nick])); |
4、在 Postman 中请求接口,Headers 中,Accept-Language:en-US,当目标语言为美国英语,文件映射的类别名为:success 时,被映射到 PHP 文件 @app/messages/en-US/success.php,如图3
5、在 Postman 中请求接口,Headers 中,Accept-Language:en-US,当目标语言为美国英语,文件映射的类别名为:app 时,未被映射到 PHP 文件 @app/messages/en-US/app.php,要翻译的信息在语言文件中未找到,会返回原始未翻译的信息,即:302011。如图4
6、编辑 E:\wwwroot\pcs-api\vendor\yiisoft\yii2\i18n\MessageSource.php,当目标语言为简体中文,响应:11, 当目标语言为美国英语,响应:21,即当目标语言为美国英语,文件映射的类别名为:app 时,跳过了翻译指定的消息的步骤。如图5、图6
1 2 | Yii::t( 'app' , '302011' ); exit ; |
1 2 3 4 5 6 7 8 9 10 11 12 13 | public function translate( $category , $message , $language ) { if ( $this ->forceTranslation || $language !== $this ->sourceLanguage) { echo 1; exit ; return $this ->translateMessage( $category , $message , $language ); } echo 2; exit ; return false; } |
7、当目标语言为美国英语,文件映射的类别名为:app 时,$this->forceTranslation 的值为 false,如图7
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public function translate( $category , $message , $language ) { var_dump( $this ->forceTranslation); exit ; if ( $this ->forceTranslation || $language !== $this ->sourceLanguage) { echo 1; exit ; return $this ->translateMessage( $category , $message , $language ); } echo 2; exit ; return false; } |
8、当目标语言为美国英语,文件映射的类别名为:success 时,$this->forceTranslation 的值为 true,如图8
1 2 | Yii::t( 'success' , '302011' ); exit ; |
9、查看 \vendor\yiisoft\yii2\i18n\I18N.php,文件映射的类别名:yii、app,始终定义类别 yii 和 app 。前者指的是 Yii 核心中使用的消息框架代码,而后者是指自定义应用程序代码的默认消息类别。其判断类别:app 是否存在,如果不存在,则覆盖,但是,其判断的层级仅为第一级,没有深入至更深的层级,因此,自定义的类别:app 会被覆盖,如图9
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | /** * @var array list of [[MessageSource]] configurations or objects. The array keys are message * category patterns, and the array values are the corresponding [[MessageSource]] objects or the configurations * for creating the [[MessageSource]] objects. * * The message category patterns can contain the wildcard `*` at the end to match multiple categories with the same prefix. * For example, `app/*` matches both `app/cat1` and `app/cat2`. * * The `*` category pattern will match all categories that do not match any other category patterns. * * This property may be modified on the fly by extensions who want to have their own message sources * registered under their own namespaces. * * The category `yii` and `app` are always defined. The former refers to the messages used in the Yii core * framework code, while the latter refers to the default message category for custom application code. * By default, both of these categories use [[PhpMessageSource]] and the corresponding message files are * stored under `@yii/messages` and `@app/messages`, respectively. * * You may override the configuration of both categories. */ public $translations ; /** * Initializes the component by configuring the default message categories. */ public function init() { parent::init(); if (!isset( $this ->translations[ 'yii' ]) && !isset( $this ->translations[ 'yii*' ])) { $this ->translations[ 'yii' ] = [ 'class' => 'yii\i18n\PhpMessageSource' , 'sourceLanguage' => 'en-US' , 'basePath' => '@yii/messages' , ]; } if (!isset( $this ->translations[ 'app' ]) && !isset( $this ->translations[ 'app*' ])) { $this ->translations[ 'app' ] = [ 'class' => 'yii\i18n\PhpMessageSource' , 'sourceLanguage' => Yii:: $app ->sourceLanguage, 'basePath' => '@app/messages' , ]; } } |
10、解决方案如下,文件映射的类别名:app 调整为 application,被映射到 PHP 文件 application.php,调整 i18n 应用组件的配置代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 'components' => [ 'i18n' => [ 'translations' => [ 'model/*' => [ 'class' => 'yii\i18n\PhpMessageSource' , 'forceTranslation' => true, 'basePath' => '@common/messages' , ], '*' => [ 'class' => 'yii\i18n\PhpMessageSource' , 'forceTranslation' => true, 'basePath' => '@app/messages' , 'fileMap' => [ 'application' => 'application.php' , 'error' => 'error.php' , 'success' => 'success.php' , ], ], ], ], ], |
11、重命名文件 \common\messages\en-US\app.php 为 \common\messages\en-US\application.php,重命名文件 \common\messages\zh-CN\app.php 为 \common\messages\zh-CN\application.php,重命名文件 \api\messages\en-US\app.php 为 \api\messages\en-US\application.php,重命名文件 \api\messages\zh-CN\app.php 为 \api\messages\zh-CN\application.php。其他应用目录下皆如此操作。将 Yii::t(‘app’, 批量替换为:Yii::t(‘application’, 。如图10

重命名文件 \common\messages\en-US\app.php 为 \common\messages\en-US\application.php,重命名文件 \common\messages\zh-CN\app.php 为 \common\messages\zh-CN\application.php,重命名文件 \api\messages\en-US\app.php 为 \api\messages\en-US\application.php,重命名文件 \api\messages\zh-CN\app.php 为 \api\messages\zh-CN\application.php。其他应用目录下皆如此操作。将 Yii::t(‘app’, 批量替换为:Yii::t(‘application’,
12、当目标语言为美国英语,文件映射的类别名为:application 时,已被映射到 PHP 文件 @app/messages/en-US/application.php,如图11
近期评论