修改原有框架中英文映射
This commit is contained in:
@@ -16,7 +16,7 @@ class ApiLang
|
||||
private const LANG_EN = 'en';
|
||||
private const LANG_ZH = 'zh';
|
||||
|
||||
/** @var array<string, array<string, string>> locale => [ 中文 => 译文 ] */
|
||||
/** @var array<string, array<string, string>> lang => [ key => message ] */
|
||||
private static array $messages = [];
|
||||
|
||||
/**
|
||||
@@ -42,21 +42,31 @@ class ApiLang
|
||||
}
|
||||
|
||||
/**
|
||||
* 翻译文案:lang=zh 返回原文(中文),lang=en 返回英文映射
|
||||
* 语言文件优先从 Webman resource/translations/api/{locale}.php 加载,否则从 app/api/lang 加载
|
||||
* 翻译文案(对外接口 message):
|
||||
* - 推荐:抛英文 key(如 USER_NOT_FOUND),根据 lang 返回对应语言
|
||||
* - 兼容:仍抛中文原文时,lang=en 按旧映射翻译,否则原样返回
|
||||
*
|
||||
* 语言文件优先从 Webman config('translation.path')/api/{lang}.php 加载
|
||||
*/
|
||||
public static function translate(string $message, ?Request $request = null): string
|
||||
{
|
||||
$lang = self::getLang($request);
|
||||
if ($lang !== self::LANG_EN) {
|
||||
return $message;
|
||||
$map = self::loadMessages($lang);
|
||||
if (isset($map[$message])) {
|
||||
return (string) $map[$message];
|
||||
}
|
||||
$map = self::loadMessages(self::LANG_EN);
|
||||
return $map[$message] ?? $message;
|
||||
|
||||
// 若传入的是中文/原文,则按固定规则生成英文 key(MSG_XXXXXXXX)再翻译
|
||||
$key = self::toMsgKey($message);
|
||||
if ($key !== null && isset($map[$key])) {
|
||||
return (string) $map[$key];
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载某语言的 API 文案(key=中文,value=译文)
|
||||
* 加载某语言的 API 文案(推荐:key=英文,value=对应语言文案)
|
||||
*/
|
||||
private static function loadMessages(string $locale): array
|
||||
{
|
||||
@@ -70,13 +80,34 @@ class ApiLang
|
||||
$path = $base . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . $locale . '.php';
|
||||
}
|
||||
}
|
||||
if (($path === null || !is_file($path)) && $locale === self::LANG_EN) {
|
||||
$path = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR . 'en.php';
|
||||
if ($path !== null && is_file($path)) {
|
||||
self::$messages[$locale] = require $path;
|
||||
return self::$messages[$locale];
|
||||
}
|
||||
self::$messages[$locale] = ($path !== null && is_file($path)) ? (require $path) : [];
|
||||
|
||||
// 回退到 app/api/lang/{lang}.php(同样使用英文 key)
|
||||
$fallback = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR . $locale . '.php';
|
||||
self::$messages[$locale] = is_file($fallback) ? (require $fallback) : [];
|
||||
return self::$messages[$locale];
|
||||
}
|
||||
|
||||
/**
|
||||
* 将原文转换为英文 key(只包含英文字符/数字/下划线):MSG_XXXXXXXX(crc32)
|
||||
* 若入参已经是英文 key,则返回 null(表示无需转换)
|
||||
*/
|
||||
private static function toMsgKey(string $message): ?string
|
||||
{
|
||||
$trim = trim($message);
|
||||
if ($trim === '') {
|
||||
return null;
|
||||
}
|
||||
// 已经是英文错误码 key(只允许 A-Z/0-9/_,且至少 3 位)
|
||||
if (preg_match('/^[A-Z0-9_]{3,}$/', $trim) === 1) {
|
||||
return null;
|
||||
}
|
||||
return 'MSG_' . strtoupper(sprintf('%08X', crc32($trim)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 带占位符的翻译,如 translateParams('当前玩家余额%s小于%s无法继续游戏', [$coin, $minCoin])
|
||||
* 先翻译再替换(en 文案使用 %s 占位)
|
||||
|
||||
Reference in New Issue
Block a user