在 Yii 2 高级项目模板中,实现 RESTFUL WEB 服务时,消息目录(messages)中配置的最佳实践

1、之前的实现如下,公共目录中的配置文件,\common\config\main.php,国际化配置如下:

    'components' => [
        'i18n' => [
            'translations' => [
                'common/*' => [
                    'class' => 'yii\i18n\PhpMessageSource',
                    'forceTranslation' => true,
                    'basePath' => '@common/messages',
                    'fileMap' => [
                        'common/app' => 'app.php',
                        'common/error' => 'error.php',
                        'common/success' => 'success.php',
                    ],
                ],
                '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、公共目录中的消息目录(messages)中的文件如下:

\common\messages\zh-CN\error.php

<?php
return [
    20000 => 'error',
    201001 => '框架服务控制台HTTP请求失败,状态码:{status_code}',
    201002 => '框架服务控制台HTTP请求失败:{first_error}',
    201003 => '框架服务控制台HTTP请求失败:{message}',
    201004 => '框架服务接口HTTP请求失败,状态码:{status_code}',
    201005 => '框架服务接口HTTP请求失败:{first_error}',
];

\common\messages\zh-CN\error.php

<?php
return [
    10000 => 'success',
];

3、接口应用中的消息目录(messages)中的文件如下:

\api\messages\zh-CN\error.php

<?php
return [
    20000 => 'error',
    224001 => '日志列表为空',
    224002 => '日志ID:{id},不存在',
    224003 => '数据过滤器验证失败:{first_error}',
    224004 => '用户ID:{id},的状态为已禁用',
    224005 => '页面列表为空',
    224006 => '页面ID:{id},不存在',
    224007 => '页面ID:{id},的状态为已删除',
    224008 => '页面ID:{id},的状态为已禁用',
    224009 => '页面ID:{id},的状态为草稿',
    226001 => '用户列表为空',
    226002 => '用户ID:{id},不存在',
    226003 => '用户ID:{id},的状态为已删除',
    226004 => '数据验证失败:{first_error}',
];

\api\messages\zh-CN\success.php

<?php
return [
    10000 => 'success',
    124001 => '获取日志列表成功',
    124002 => '获取日志详情成功',
    124003 => '获取页面列表成功',
    124004 => '获取页面详情成功',
    124005 => '创建页面成功',
    124006 => '更新页面成功',
    124007 => '删除页面成功',
    126001 => '获取用户列表成功',
    126002 => '获取用户详情成功',
    126003 => '创建用户成功',
    126004 => '更新用户成功',
    126005 => '删除用户成功',
];

4、公共目录中的 Yii::t() 方法实现如下:

 throw new ServerErrorHttpException(Yii::t('common/error', Yii::t('common/error', Yii::t('common/error', '201001'), ['status_code' => $response->getStatusCode()])), 201001);

5、接口应用中的 Yii::t() 方法实现如下:

 return ['code' => 226004, 'message' => Yii::t('error', Yii::t('error', Yii::t('error', '226004'), ['first_error' => $firstError]))];

6、之前的实现存在的问题如下:

(1)公共目录中的 Yii::t() 方法实现 Yii::t(‘common/error’ 有所冗余,期待 Yii::t(‘error’ 的实现
(2)接口应用中如果要包含公共目录中的要翻译的消息,Yii::t() 方法必须实现 Yii::t(‘common/error’,要包含接口应用中的要翻译的消息,Yii::t() 方法必须实现 Yii::t(‘error’,需要明确得知要翻译的消息的位置,存在很大的出错可能性,且实现不够纯粹,有所混杂

7、基于存在的问题,解决方案调整如下,公共目录中的配置文件,i18n 应用组件配置的调整(消息类别:删除 common/*),\common\config\main.php,国际化配置如下:

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

8、公共目录中的消息目录(messages)中的文件不做调整,保持原样

9、接口应用中的消息目录(messages)中的文件如下:

\api\messages\zh-CN\error.php

<?php
$commonMessages = require __DIR__ . '/../../../common/messages/zh-CN/error.php';
$messages = [
    224001 => '日志列表为空',
    224002 => '日志ID:{id},不存在',
    224003 => '数据过滤器验证失败:{first_error}',
    224004 => '用户ID:{id},的状态为已禁用',
    224005 => '页面列表为空',
    224006 => '页面ID:{id},不存在',
    224007 => '页面ID:{id},的状态为已删除',
    224008 => '页面ID:{id},的状态为已禁用',
    224009 => '页面ID:{id},的状态为草稿',
    226001 => '用户列表为空',
    226002 => '用户ID:{id},不存在',
    226003 => '用户ID:{id},的状态为已删除',
    226004 => '数据验证失败:{first_error}',
];
return $commonMessages + $messages;

\api\messages\zh-CN\success.php

<?php
$commonMessages = require __DIR__ . '/../../../common/messages/zh-CN/success.php';
$messages = [
    124001 => '获取日志列表成功',
    124002 => '获取日志详情成功',
    124003 => '获取页面列表成功',
    124004 => '获取页面详情成功',
    124005 => '创建页面成功',
    124006 => '更新页面成功',
    124007 => '删除页面成功',
    126001 => '获取用户列表成功',
    126002 => '获取用户详情成功',
    126003 => '创建用户成功',
    126004 => '更新用户成功',
    126005 => '删除用户成功',
];
return $commonMessages + $messages;

10、公共目录中的 Yii::t() 方法实现如下:

 throw new ServerErrorHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '201001'), ['status_code' => $response->getStatusCode()])), 201001);

11、接口应用中的 Yii::t() 方法实现如下:

 return ['code' => 226004, 'message' => Yii::t('error', Yii::t('error', Yii::t('error', '226004'), ['first_error' => $firstError]))];

12、之前的实现存在的问题,已经得到解决,如下:

(1)公共目录中的 Yii::t() 方法实现 Yii::t(‘error’,仅需要保证对应的 code 存在于公共目录中的消息目录(messages)中
(2)接口应用中如果要包含公共目录中的要翻译的消息,Yii::t() 方法必须实现 Yii::t(‘error’,要包含接口应用中的要翻译的消息,Yii::t() 方法必须实现 Yii::t(‘error’,无需明确得知要翻译的消息的位置,公共目录与接口应用中的消息目录(messages)皆可使用
(3)存在的一个小问题,如果 公共目录中 与 接口应用中 皆存在一个同样的 code,此时接口应用中的值不会覆盖公共目录中的值,原因在于接口应用中消息文件未使用 array_merge 方法,因为数组索引为数字,如果使用 array_merge 方法,数字键名将会被重新编号,索引会从 0 开始,因此,保留原有数组并只想新的数组附加到后面,用 + 运算符,附加的话,在两个数组中存在相同的键名时,第一个数组中的同键名的元素将会被保留,第二个数组中的元素将会被忽略

永夜