Files
x-server-mobile/backend/app/util/Lang.php
T

171 lines
4.3 KiB
PHP
Raw Normal View History

<?php
namespace app\util;
/**
* 多语言翻译类
* 支持:中文(zh)、英文(en)、俄语(ru)、西语(es)、法语(fr)
*/
class Lang
{
private static ?array $translations = null;
private static string $locale = 'zh';
private static string $fallbackLocale = 'zh';
/**
* 支持的语言列表
*/
public const SUPPORTED_LOCALES = ['zh', 'en', 'ru', 'es', 'fr'];
/**
* 语言名称映射
*/
public const LOCALE_NAMES = [
'zh' => '简体中文',
'en' => 'English',
'ru' => 'Русский',
'es' => 'Español',
'fr' => 'Français',
];
/**
* 初始化翻译
*/
private static function loadTranslations(): void
{
if (self::$translations !== null) {
return;
}
self::$translations = [];
foreach (self::SUPPORTED_LOCALES as $locale) {
$file = base_path() . "/lang/{$locale}.php";
if (file_exists($file)) {
self::$translations[$locale] = require $file;
}
}
}
/**
* 设置当前语言
*/
public static function setLocale(string $locale): void
{
if (in_array($locale, self::SUPPORTED_LOCALES)) {
self::$locale = $locale;
}
}
/**
* 获取当前语言
*/
public static function getLocale(): string
{
return self::$locale;
}
/**
* 从请求中获取语言
*/
public static function detectFromRequest(): string
{
// 从请求头获取语言
$request = \request();
$acceptLanguage = $request->header('Accept-Language');
if ($acceptLanguage) {
// 解析 Accept-Language 头
$locales = explode(',', $acceptLanguage);
foreach ($locales as $locale) {
$locale = trim(strstr($locale, ';', true));
$locale = substr($locale, 0, 2);
if (in_array($locale, self::SUPPORTED_LOCALES)) {
return $locale;
}
}
}
// 从查询参数获取
$lang = $request->input('lang');
if ($lang && in_array($lang, self::SUPPORTED_LOCALES)) {
return $lang;
}
return self::$fallbackLocale;
}
/**
* 翻译文本
*
* @param string $key 翻译键,使用点号分隔,如 'common.confirm'
* @param array $params 替换参数
* @param string|null $locale 指定语言,null 则使用当前语言
* @return string 翻译后的文本
*/
public static function get(string $key, array $params = [], ?string $locale = null): string
{
self::loadTranslations();
$locale = $locale ?? self::$locale;
// 获取翻译值
$value = self::getTranslationValue($key, $locale);
// 替换参数
if (!empty($params)) {
foreach ($params as $search => $replace) {
$value = str_replace(':' . $search, $replace, $value);
$value = str_replace('{' . $search . '}', $replace, $value);
}
}
return $value;
}
/**
* 获取翻译值
*/
private static function getTranslationValue(string $key, string $locale): string
{
$keys = explode('.', $key);
$value = self::$translations[$locale] ?? [];
foreach ($keys as $k) {
if (isset($value[$k])) {
$value = $value[$k];
} else {
// 尝试使用回退语言
if ($locale !== self::$fallbackLocale) {
return self::getTranslationValue($key, self::$fallbackLocale);
}
return $key;
}
}
return is_string($value) ? $value : $key;
}
/**
* 判断翻译是否存在
*/
public static function has(string $key, ?string $locale = null): bool
{
self::loadTranslations();
$locale = $locale ?? self::$locale;
$keys = explode('.', $key);
$value = self::$translations[$locale] ?? [];
foreach ($keys as $k) {
if (isset($value[$k])) {
$value = $value[$k];
} else {
return false;
}
}
return true;
}
}