MENU

一个简单的Language类来处理多语言支持

July 23, 2024 • 已被 198 位童鞋围观过 • 代码分享

支持读取 cookie["language"]或者是获取 $_GET["language"] 参数来判断当前语言选项

默认语言支持 中文 英文 法语 德语 等

如果不再支持的语言中 返回英文 且重写 cookie["Language"]

支持语言回退 变量替换等功能

<?php
namespace App\Utility;
class Language
{
    private $langData = [];
    private $currentLang;
    private $supportedLangs = [
        "en" => "English",
        "zh" => "中文简体",
        "fr" => "Français",
        "de" => "Deutsch"
    ];
    private $defaultLang = 'en';

    public function __construct()
    {
        $this->setLanguage();
        $this->loadLanguageData();
    }

    private function setLanguage()
    {
        $lang = $_GET['language'] ?? $_COOKIE['language'] ?? $this->defaultLang;
        $lang = strtolower(substr($lang, 0, 2)); // 只取前两个字符并转换为小写

        if (!array_key_exists($lang, $this->supportedLangs)) {
            $lang = $this->defaultLang;
        }

        $this->currentLang = $lang;
        setcookie('language', $lang, time() + (86400 * 30), "/"); // 设置 cookie,有效期 30 天
    }

    private function loadLanguageData()
    {
        $filePath = __DIR__ . "/lang/{$this->currentLang}.json";
        if (file_exists($filePath)) {
            $this->langData = json_decode(file_get_contents($filePath), true);
        } else {
            throw new Exception("Language file not found: {$this->currentLang}");
        }
    }

    public function get($key, $replacements = [], $default = null)
    {
        $value = $this->getFromLanguageData($key);
  
        if ($value === null && $this->currentLang !== $this->defaultLang) {
            // 语言回退:如果在当前语言中找不到,尝试在默认语言中查找
            $defaultFilePath = __DIR__ . "/lang/{$this->defaultLang}.json";
            $defaultLangData = json_decode(file_get_contents($defaultFilePath), true);
            $value = $this->getFromLanguageData($key, $defaultLangData);
        }

        if ($value === null) {
            return $default ?? $key;
        }

        // 变量替换
        if (is_string($value) && !empty($replacements)) {
            foreach ($replacements as $placeholder => $replacement) {
                $value = str_replace(":$placeholder", $replacement, $value);
            }
        }

        return $value;
    }

    private function getFromLanguageData($key, $data = null)
    {
        $keys = explode('.', $key);
        $value = $data ?? $this->langData;

        foreach ($keys as $nested) {
            if (isset($value[$nested])) {
                $value = $value[$nested];
            } else {
                return null;
            }
        }

        return $value;
    }

    //获取当前语言ID
    public function getCurrentLanguage(){
        return $this->currentLang;
    }
    //获取当前语言ID
    public function id(){
        return $this->currentLang;
    }
    //获取语言左右结构
    public function direction(){
        if($this->currentLang == "ar" || $this->currentLang == "fa"){
            return "rtl";
        }else{
            return "ltr";
        }
    }
    //获取当前语言名字
    public function getCurrentLanguageName(){
        return $this->supportedLangs[$this->currentLang];
    }
    //获取支持语言表
    public function getSupportedLanguages(){
        return $this->supportedLangs;
    }
}

使用示例如下:

Json数据

{
  "user": {
    "auth": {
      "register": {
        "password_mismatch": "Passwords do not match!",
        "email_exists": "Email already exists. Please use a different one!"
      }
    },
    "welcome": "Welcome, :name!"
  }
}
// 初始化语言类
$lang = new Language();

// 获取翻译
echo $lang->get('user.auth.register.password_mismatch');

// 使用变量替换
echo $lang->get('user.welcome', ['name' => 'John']);

// 获取当前语言代码
echo $lang->getCurrentLanguage();

// 获取当前语言名称
echo $lang->getCurrentLanguageName();

// 获取支持的语言列表
print_r($lang->getSupportedLanguages());

// 获取语言选项(适用于下拉菜单)
$languageOptions = $lang->getLanguageOptions();
foreach ($languageOptions as $option) {
    echo "<option value='{$option['code']}'" . ($option['selected'] ? ' selected' : '') . ">{$option['name']}</option>";
}