国际化 – 永夜 https://www.shuijingwanwq.com 没有不值得去解决的问题,也没有不值得去学习的技术! Thu, 05 Aug 2021 02:30:28 +0000 zh-Hans hourly 1 https://wordpress.org/?v=7.0 在 Yii 2.0 中实现国际化,翻译英文描述中的一部分为中文描述(微信接口返回的英文信息) https://www.shuijingwanwq.com/2021/08/05/5144/ https://www.shuijingwanwq.com/2021/08/05/5144/#respond Thu, 05 Aug 2021 02:30:28 +0000 https://www.shuijingwanwq.com/?p=5144 浏览量: 113 1、在请求微信接口时,返回码:45028,返回的英文信息:has no masssend quota rid: 6103df2e-1505ba73-0eb14e1c。如图1
在请求微信接口时,返回码:45028,返回的英文信息:has no masssend quota rid: 6103df2e-1505ba73-0eb14e1c

图1



{
  "errcode": 45028,
  "errmsg": "has no masssend quota rid: 6103df2e-1505ba73-0eb14e1c"
}


2、代码实现如下


$responseData = $wxServiceApi::wxMessageSendAll($requestData);
if (!isset($responseData['msg_id'])) {
    $errcode = array_key_exists('errcode',$responseData)?$responseData['errcode']:205100;
    throw new ServerErrorHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '205100'), ['error_code' => $errcode, 'error_msg' => $responseData['errmsg']])), 205100);
}


3、计划将错误信息:has no masssend quota rid: 6103df2e-1505ba73-0eb14e1c 翻译为:没有群发配额。rid: 6103df2e-1505ba73-0eb14e1c。如图2
计划将错误信息:has no masssend quota rid: 6103df2e-1505ba73-0eb14e1c 翻译为:没有群发配额。rid: 6103df2e-1505ba73-0eb14e1c

图2

4、添加文件 common/messages/en-US/wx.php、common/messages/zh-CN/wx.php、wx/messages/en-US/wx.php、wx/messages/zh-CN/wx.php。如图3
添加文件 common/messages/en-US/wx.php、common/messages/zh-CN/wx.php、wx/messages/en-US/wx.php、wx/messages/zh-CN/wx.php

图3

common/messages/en-US/wx.php
<pre class="wp-block-syntaxhighlighter-code">

<?php
return [
];


</pre>
common/messages/zh-CN/wx.php
<pre class="wp-block-syntaxhighlighter-code">

<?php
return [
    'has no masssend quota' => '没有群发配额(订阅号为每天 1 次,服务号为每月 4 次)。',
    'invalid content' => '无效内容(内容中包含音频)。',
];


</pre>
wx/messages/en-US/wx.php
<pre class="wp-block-syntaxhighlighter-code">

<?php
$commonMessages = require __DIR__ . '/../../../common/messages/en-US/wx.php';
$messages = [
];
return $commonMessages + $messages;


</pre>
wx/messages/zh-CN/wx.php
<pre class="wp-block-syntaxhighlighter-code">

<?php
$commonMessages = require __DIR__ . '/../../../common/messages/zh-CN/wx.php';
$messages = [
];
return $commonMessages + $messages;


</pre>
5、代码实现如下。其中代码:substr($responseData[‘errmsg’], 0, $pos) 的结果为:has no masssend quota。其中代码:substr($responseData[‘errmsg’], $pos) 的结果为: rid: 6103df2e-1505ba73-0eb14e1c。将:has no masssend quota 翻译为:没有群发配额。后,再拼接上: rid: 6103df2e-1505ba73-0eb14e1c。


$responseData = $wxServiceApi::wxMessageSendAll($requestData);
if (!isset($responseData['msg_id'])) {
    $errcode = $responseData['errcode'] ?? 205100;
    $pos = strpos($responseData['errmsg'], ' rid:');
    $errorMsg = Yii::t('wx', substr($responseData['errmsg'], 0, $pos)) . substr($responseData['errmsg'], $pos);
    throw new ServerErrorHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '205100'), ['error_code' => $errcode, 'error_msg' => $errorMsg])), 205100);
}


6、针对返回的英文信息:invalid content hint: [pzRHda0286d228] rid: 61041ffe-5cefd269-6c9611ff,完善后的代码如下。根源在于源语言的消息不支持模糊匹配。


$responseData = $wxServiceApi::wxMessageSendAll($requestData);
if (!isset($responseData['msg_id'])) {
    $errcode = $responseData['errcode'] ?? 205100;
    $errorMsg = '';
    $pos = strpos($responseData['errmsg'], ' hint:');
    if ($pos === false) {
        $pos = strpos($responseData['errmsg'], ' rid:');
    }
    if ($pos !== false) {
        $errorMsg = Yii::t('wx', substr($responseData['errmsg'], 0, $pos)) . substr($responseData['errmsg'], $pos);
    }
    throw new ServerErrorHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '205100'), ['error_code' => $errcode, 'error_msg' => $errorMsg])), 205100);
}


7、测试翻译结果,has no masssend quota rid: 610a50c5-26966176-7cceb46e 已经被翻译为:没有群发配额(订阅号为每天 1 次,服务号为每月 4 次)。rid: 610a50c5-26966176-7cceb46e。符合预期。如图4
测试翻译结果,has no masssend quota rid: 610a50c5-26966176-7cceb46e 已经被翻译为:没有群发配额(订阅号为每天 1 次,服务号为每月 4 次)。rid: 610a50c5-26966176-7cceb46e。符合预期

图4

8、测试翻译结果,invalid content hint: [dN7TKA0474d139] rid: 610a5a7a-5907e6c6-270b8278 已经被翻译为:无效内容(内容中包含音频)。 hint: [dN7TKA0474d139] rid: 610a5a7a-5907e6c6-270b8278。符合预期。如图5
测试翻译结果,invalid content hint: [dN7TKA0474d139] rid: 610a5a7a-5907e6c6-270b8278 已经被翻译为:无效内容(内容中包含音频)。 hint: [dN7TKA0474d139] rid: 610a5a7a-5907e6c6-270b8278。符合预期

图5

9、由于 invalid image size 还未被添加至语言包中,因此:invalid image size hint: [cl_6Oa0457mp13] rid: 6103c6d0-481a4bed-73e7120a 保持原样。符合预期。
<pre class="wp-block-syntaxhighlighter-code">

<?php
return [
    'has no masssend quota' => '没有群发配额(订阅号为每天 1 次,服务号为每月 4 次)。',
    'invalid content' => '无效内容(内容中包含音频)。',
    'invalid image size' => '图片尺寸太大(大小必须在10MB以下)。',
];


</pre>
11、测试翻译结果,invalid image size hint: [flp8Ba0298w689] rid: 610a6969-72bb79c0-4b069755 已经被翻译为:invalid image size hint: [flp8Ba0298w689] rid: 610a6969-72bb79c0-4b069755。蓝框中是翻译前的英文信息,红框中是翻译后的中文信息。符合预期。如图6
测试翻译结果,invalid image size hint: [flp8Ba0298w689] rid: 610a6969-72bb79c0-4b069755 已经被翻译为:invalid image size hint: [flp8Ba0298w689] rid: 610a6969-72bb79c0-4b069755。蓝框中是翻译前的英文信息,红框中是翻译后的中文信息。符合预期

图6

]]>
https://www.shuijingwanwq.com/2021/08/05/5144/feed/ 0
Yii 2 高级项目模板,国际化的消息翻译服务的 Bug (当目标语言为美国英语,文件映射的类别名为:app 时,未被映射到 PHP 文件 @app/messages/en-US/app.php) 的分析解决 https://www.shuijingwanwq.com/2019/07/19/3355/ https://www.shuijingwanwq.com/2019/07/19/3355/#respond Fri, 19 Jul 2019 07:06:10 +0000 forceTranslation]]> translations['yii']]]> translations['app']]]> http://www.shuijingwanwq.com/?p=3355 浏览量: 138 1、i18n 应用组件的配置代码如下:


    '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
在 Postman 中请求接口,Headers 中,Accept-Language:zh-CN,当目标语言为简体中文,文件映射的类别名为:success 时,被映射到 PHP 文件 @app/messages/zh-CN/success.php

图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
在 Postman 中请求接口,Headers 中,Accept-Language:zh-CN,当目标语言为简体中文,文件映射的类别名为:app 时,被映射到 PHP 文件 @app/messages/zh-CN/app.php

图2



$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
在 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
在 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
当目标语言为简体中文,响应:11

图5

当目标语言为美国英语,响应:21,即当目标语言为美国英语,文件映射的类别名为:app 时,跳过了翻译指定的消息的步骤

图6



        Yii::t('app', '302011');
        exit;




    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
当目标语言为美国英语,文件映射的类别名为:app 时,$this->forceTranslation 的值为 false

图7



    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
当目标语言为美国英语,文件映射的类别名为:success 时,$this->forceTranslation 的值为 true

图8



        Yii::t('success', '302011');
        exit;


9、查看 \vendor\yiisoft\yii2\i18n\I18N.php,文件映射的类别名:yii、app,始终定义类别 yii 和 app 。前者指的是 Yii 核心中使用的消息框架代码,而后者是指自定义应用程序代码的默认消息类别。其判断类别:app 是否存在,如果不存在,则覆盖,但是,其判断的层级仅为第一级,没有深入至更深的层级,因此,自定义的类别:app 会被覆盖,如图9
查看 \vendor\yiisoft\yii2\i18n\I18N.php,文件映射的类别名:yii、app,始终定义类别 yii 和 app 。前者指的是 Yii 核心中使用的消息框架代码,而后者是指自定义应用程序代码的默认消息类别。其判断类别:app 是否存在,如果不存在,则覆盖,但是,其判断的层级仅为第一级,没有深入至更深的层级,因此,自定义的类别:app 会被覆盖

图9



    /**
     * @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 应用组件的配置代码如下:


    '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',

重命名文件 \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
当目标语言为美国英语,文件映射的类别名为:application 时,已被映射到 PHP 文件 @app/messages/en-US/application.php

图11

 ]]>
https://www.shuijingwanwq.com/2019/07/19/3355/feed/ 0
在Yii 2.0 中实现属性标签的国际化支持 https://www.shuijingwanwq.com/2016/06/07/1104/ https://www.shuijingwanwq.com/2016/06/07/1104/#respond Tue, 07 Jun 2016 05:37:45 +0000 http://www.shuijingwanwq.com/?p=1104 浏览量: 68

1、因为是生成一些公有的模型至common目录中,且配置了多个数据库连接组件,因此针对kcucDb的模型皆以Kcuc为前缀,以防止命名冲突(不然,不推荐模型名加上相应表前缀),如图1:

针对kcucDb的模型皆以Kcuc为前缀,以防止命名冲突

针对kcucDb的模型皆以Kcuc为前缀,以防止命名冲突

2、Use Table Prefix:使用表前缀要勾选;Generate Labels from DB Comments:基于DB注释生成标签不勾选(因为后期要进行人工翻译处理);Enable I18N:启用国际化要勾选;Message Category:信息分类设置为commonAttributeLabels/kcucMembers,这是启用国际化的情况下被Yii::t()所使用的类别,以用于当前模型类下的属性标签,生成后如图2:

Generate Labels from DB Comments:基于DB注释生成标签不勾选(因为后期要进行人工翻译处理)

Generate Labels from DB Comments:基于DB注释生成标签不勾选(因为后期要进行人工翻译处理)

3、在应用程序中按下面的代码来配置消息翻译,如图3:

模式 commonAttributeLabels* 表示所有以 commonAttributeLabels 开头的消息类别名称都使用这个翻译的消息来源。

模式 attributeLabels* 表示所有以 attributeLabels 开头的消息类别名称都使用这个翻译的消息来源。其根路径为当前应用。

模式 * 表示指定默认翻译。其根路径为当前应用。

在应用程序中按下面的代码来配置消息翻译

在应用程序中按下面的代码来配置消息翻译

4、新建\common\messages\zh-CN\commonAttributeLabels\kcucMembers.php、\common\messages\zh-CN\not_specified_category.php,如图4:

新建\common\messages\zh-CN\commonAttributeLabels\kcucMembers.php、\common\messages\zh-CN\not_specified_category.php

新建\common\messages\zh-CN\commonAttributeLabels\kcucMembers.php、\common\messages\zh-CN\not_specified_category.php

5、编辑\common\messages\zh-CN\commonAttributeLabels\kcucMembers.php,如图5:

编辑消息翻译文件

编辑消息翻译文件

6、小技巧:zh-CN下可先勾选Generate Labels from DB Comments,Preview时复制模型类下的public function attributeLabels(),再编辑,如图6;

小技巧:zh-CN下可先勾选Generate Labels from DB Comments,Preview时复制模型类下的public function attributeLabels(),再编辑

小技巧:zh-CN下可先勾选Generate Labels from DB Comments,Preview时复制模型类下的public function attributeLabels(),再编辑

7、测试,
$model = new \common\models\KcucMembers;

// 显示为 “Mobile”
echo $model->getAttributeLabel(‘mobile’);

默认的 [[yii\base\Application::$sourceLanguage|源语言]] 值是 en-US,即美国英语,保持不变,如果[[yii\base\Application::$language|目标语言]]未设置,或者设置为en-US,则
打印出”Mobile”,如图7:

如果[[yii\base\Application::$language|目标语言]]未设置,或者设置为en-US,则 打印出"Mobile"

如果[[yii\base\Application::$language|目标语言]]未设置,或者设置为en-US,则
打印出”Mobile”

8、默认的 [[yii\base\Application::$sourceLanguage|源语言]] 值是 en-US,即美国英语,保持不变,如果[[yii\base\Application::$language|目标语言]]设置为zh-CN,则
打印出”用户手机”,如图8:

如果[[yii\base\Application::$language|目标语言]]设置为zh-CN,则 打印出"用户手机"

如果[[yii\base\Application::$language|目标语言]]设置为zh-CN,则
打印出”用户手机”

]]>
https://www.shuijingwanwq.com/2016/06/07/1104/feed/ 0