🌐 多语言

ThinkAdmin 基于 ThinkPHP 提供完善的多语言包管理功能,支持国际化应用开发。

📚 基础概念

什么是多语言?

多语言(Internationalization,简称 i18n)是指系统支持多种语言显示,用户可以根据自己的语言偏好选择界面语言。

简单理解:就像手机可以切换系统语言一样,ThinkAdmin 也支持切换界面语言。

实际场景

  • 中国用户看到中文界面
  • 美国用户看到英文界面
  • 日本用户看到日文界面

多语言的优势

  • 用户体验更好:用户使用自己熟悉的语言,操作更顺畅
  • 市场拓展:支持多语言可以拓展国际市场
  • 专业形象:多语言支持提升产品专业度

🤔 为什么需要?

场景1:国际化应用

// 如果只支持中文
echo "欢迎使用";  // 中国用户能看懂

// 但外国用户看不懂,需要多语言
echo lang('welcome');  // 根据用户语言自动显示
// 中文用户看到:欢迎使用
// 英文用户看到:Welcome

场景2:多地区部署

  • 中国大陆:使用简体中文
  • 中国台湾:使用繁体中文
  • 美国:使用英文
  • 日本:使用日文

场景3:用户个性化

  • 用户A喜欢中文界面
  • 用户B喜欢英文界面
  • 系统根据用户设置自动切换

⚙️ 工作原理

ThinkAdmin 使用语言包文件存储翻译文本,通过简单的函数调用实现多语言切换。

工作原理

步骤1:定义语言键 在代码中使用 lang('key') 函数,而不是直接写死文本:

// ❌ 不推荐:直接写死文本
echo "欢迎使用";

// ✅ 推荐:使用语言键
echo lang('welcome');

步骤2:创建语言包文件 在语言包文件中定义翻译:

<?php
// app/admin/lang/zh-cn.php(中文语言包)
return [
    'welcome' => '欢迎使用',
    'login_success' => '登录成功',
];

// app/admin/lang/en-us.php(英文语言包,必须放在应用语言包目录下)
return [
    'welcome' => 'Welcome',
    'login_success' => 'Login Success',
];

步骤3:系统自动加载 用户切换语言后,系统自动加载对应的语言包:

// 用户选择中文
// 系统加载 app/admin/lang/zh-cn.php
echo lang('welcome');  // 输出:欢迎使用

// 用户选择英文
// 系统加载 app/admin/lang/en-us.php(应用语言包)
echo lang('welcome');  // 输出:Welcome

步骤4:自动显示与回退机制 系统根据当前语言设置自动显示对应文本,无需手动判断。

回退机制

  • 当使用 lang('key') 时,系统会先查找当前语言的语言包文件(如 app/admin/lang/en-us.php
  • 如果当前语言包中找不到对应的翻译,系统会自动回退到中文语言包(app/admin/lang/zh-cn.php)查找
  • 如果中文语言包中也找不到,才会返回语言键本身
  • 这样可以确保即使某些语言包不完整,也能显示中文内容,提升用户体验

相关概念说明

语言包(Language Pack)

  • 存储翻译文本的 PHP 文件
  • 文件格式:返回关联数组
  • 文件位置:
    • 应用语言包:app/模块名/lang/ 目录(如 app/admin/lang/app/index/lang/
  • 文件命名:与语言代码一致(如 zh-cn.phpen-us.php

语言键(Language Key)

  • 用于标识文本的唯一标识符
  • 格式:字符串,支持点号分隔(如 user.namemenu.user.list
  • 作用:在代码中引用翻译文本
  • 示例:lang('welcome') 中的 'welcome' 就是语言键

默认语言

  • 系统默认使用的语言
  • 配置位置:config/lang.php
  • 默认值:zh-cn(中文)
  • 作用:当用户未选择语言或语言包不存在时使用

语言切换

  • 用户选择不同语言的过程
  • URL 参数切换:使用 ?lang=en 参数可以快速切换语言
  • 浏览器语言:如果没有 URL 参数,系统会使用浏览器语言
  • 配置要求:需要在 config/lang.php 中配置允许的语言列表和 lang 映射关系
  • 效果:界面文本立即切换为对应语言

🚀 主要功能

  • 多语言支持: 支持多种语言包切换
  • 分层管理: 应用、动态两种语言包类型
  • 灵活配置: 支持动态配置语言参数
  • 数据字典: 支持数据库存储的动态语言包
  • 自动加载: 自动加载对应语言包文件
  • 缓存优化: 支持语言包缓存提升性能

📋 语言包类型

ThinkAdmin 支持两种语言包类型,每种类型有不同的作用范围和适用场景:

📱 应用语言包

应用语言包仅在当前应用有效,适合定义应用特定的文本。

什么是应用语言包?

  • 只在当前应用有效的语言包
  • 不同应用可以有相同的语言键,但显示不同的文本
  • 适合应用特定的业务文本

重要说明

  • 不同语言对应不同的语言包文件:每种语言必须有对应的语言包文件,如 zh-cn.php(中文)、en-us.php(英文)、ja-jp.php(日文)等
  • 文件命名规则:语言包文件名必须与语言代码一致(如 zh-cn.phpen-us.php
  • 回退机制:当使用 lang() 函数时,如果当前语言包中找不到翻译,系统会自动回退到中文语言包(zh-cn.php)查找

文件位置

app/
  ├── admin/              # admin 模块
  │   └── lang/           # admin 模块的语言包目录
  │       ├── zh-cn.php   # admin 模块的中文语言包
  │       ├── en-us.php   # admin 模块的英文语言包
  │       └── ja-jp.php   # admin 模块的日文语言包(示例)
  └── index/              # index 模块
      └── lang/           # index 模块的语言包目录
          ├── zh-cn.php   # index 模块的中文语言包
          └── en-us.php   # index 模块的英文语言包

重要提示:应用语言包必须在 app/模块名/lang/ 目录下,不支持项目根目录的 app/lang/ 目录。例如:

  • ✅ 正确:app/admin/lang/zh-cn.php
  • ❌ 错误:app/lang/zh-cn.php(不存在此路径)

创建应用语言包

<?php
// app/admin/lang/zh-cn.php(后台管理应用)
return [
    'user_management' => '用户管理',
    'add_user' => '添加用户',
    'edit_user' => '编辑用户',
    'delete_user' => '删除用户',
    'user_list' => '用户列表',
];

// app/index/lang/zh-cn.php(前台应用)
return [
    'user_management' => '个人中心',  // 相同的键,不同的值
    'add_user' => '注册账号',
    'edit_user' => '修改资料',
    'delete_user' => '注销账号',
    'user_list' => '我的信息',
];

在不同应用中使用

<?php
// 在 admin 应用中
echo lang('user_management');  // 输出:用户管理

// 在 index 应用中
echo lang('user_management');  // 输出:个人中心(不同的文本)

适用场景

  • ✅ 应用特定的业务文本
  • ✅ 不同应用需要不同翻译的场景
  • ✅ 应用专属的菜单、按钮文本

🔄 动态语言包

动态语言包存储在数据库中,可以通过后台管理界面编辑,无需修改代码文件。

什么是动态语言包?

  • 存储在数据库中的语言包
  • 可以通过后台界面编辑
  • 适合需要频繁修改或后期修补的语言包

为什么需要动态语言包?

  • 无需修改代码:修改语言包不需要改代码文件
  • 实时生效:修改后立即生效,无需重启
  • 便于管理:通过后台界面统一管理
  • 支持多用户:不同用户可以编辑不同的语言包

内置动态语言包

ThinkAdmin 已内置两个动态语言包:

  1. 英文字典

    • type: 英文字典
    • 用于英文翻译字典
    • 存储位置:数据字典表
    • 用途:将中文翻译为英文
  2. 英文菜单

    • type: 英文菜单
    • 专门用于系统后台菜单的英文翻译
    • 存储位置:数据字典表
    • 用途:后台管理系统的菜单多语言支持
    • 注意:这是专门为后台菜单设计的,不是用于普通文本翻译

查看内置语言包

<?php
// 在后台数据字典中查看
// 系统管理 → 数据字典 → 查找 type = '英文字典' 或 '英文菜单'

创建自定义动态语言包

ThinkAdmin 支持通过数据字典创建自定义动态语言包,可以支持更多语言(英文、日文、韩文、法文等)。动态语言包是通过在语言包文件中直接读取数据字典实现的,参考 think-library/src/lang/en-us.php 的实现方式。

重要提示:数据字典类型应该与语言包文件对应,比如:

  • 英文语言包 en-us.php 读取 英文字典英文菜单 类型的数据字典(已有类型,无需新建)
  • 其他语言包可以创建对应的数据字典类型,如 日文字典日文菜单韩文字典韩文菜单法文字典法文菜单

⚠️ 重要字典和菜单必须同步配置!每种语言的字典类型和菜单类型必须同时存在,否则后台切换语言时会显示不完整:

  • 字典类型:用于普通文本翻译(页面内容、提示信息等)
  • 菜单类型专门用于系统后台菜单翻译(左侧导航菜单、顶部菜单等)
  • 如果只配置字典不配置菜单,后台菜单会显示为中文或语言键
  • 如果只配置菜单不配置字典,普通文本会显示为中文或语言键
  • 必须同时配置字典和菜单,才能完整切换语言

实现方式:在语言包文件中读取数据字典

<?php
// app/admin/lang/en-us.php(英文语言包)
use think\admin\model\SystemBase;

// 从数据字典读取英文字典(已有类型,直接使用)
$customLangs = [];
if (count($items = SystemBase::items('英文字典')) > 0) {
    $customLangs = array_column($items, 'name', 'code');
}

// 从数据字典读取英文菜单(已有类型,直接使用)
// ⚠️ 注意:字典和菜单必须同时读取,否则语言切换不完整
if (count($items = SystemBase::items('英文菜单')) > 0) {
    $menus = array_column($items, 'name', 'code');
    foreach ($menus as $key => $name) {
        $customLangs["menus_{$key}"] = $name;
    }
}

// 合并静态翻译和动态翻译
return array_merge([
    // 静态翻译内容
    'welcome' => 'Welcome',
    'login_success' => 'Login Success',
    // ... 其他静态翻译
], $customLangs);  // 合并从数据字典读取的翻译(包括字典和菜单)

多语言支持示例

ThinkAdmin 可以轻松支持更多语言,只需创建对应的语言包文件和数据字典类型:

<?php
// app/admin/lang/ja-jp.php(日文语言包)
use think\admin\model\SystemBase;

// 从数据字典读取日文字典(需要先在数据字典中创建"日文字典"类型)
$customLangs = [];
if (count($items = SystemBase::items('日文字典')) > 0) {
    $customLangs = array_column($items, 'name', 'code');
}

// 从数据字典读取日文菜单(需要先在数据字典中创建"日文菜单"类型)
if (count($items = SystemBase::items('日文菜单')) > 0) {
    $menus = array_column($items, 'name', 'code');
    foreach ($menus as $key => $name) {
        $customLangs["menus_{$key}"] = $name;
    }
}

return array_merge([
    'welcome' => 'ようこそ',
    'login_success' => 'ログイン成功',
], $customLangs);
<?php
// app/admin/lang/ko-kr.php(韩文语言包)
use think\admin\model\SystemBase;

// 从数据字典读取韩文字典(需要先在数据字典中创建"韩文字典"类型)
$customLangs = [];
if (count($items = SystemBase::items('韩文字典')) > 0) {
    $customLangs = array_column($items, 'name', 'code');
}

return array_merge([
    'welcome' => '환영합니다',
    'login_success' => '로그인 성공',
], $customLangs);

步骤1:在数据字典中添加数据

通过后台系统管理界面添加数据:

  • 进入:系统管理 → 数据字典
  • 添加数据:
    • type: 英文字典(数据字典类型,已有类型,直接使用)
    • code: welcome(作为语言键)
    • name: Welcome to ThinkAdmin(翻译内容)

步骤2:在代码中使用

<?php
// 直接使用数据字典中的 code 作为语言键
echo lang('welcome');  
// 系统会从语言包中查找,如果语言包中读取了数据字典,则返回对应的翻译

适用场景

  • ✅ 需要频繁修改的语言包
  • ✅ 需要通过后台管理的语言包
  • ✅ 后期修补错漏的语言包
  • ✅ 多用户协作编辑的语言包
  • ✅ 支持更多语言(英文、日文、韩文、法文等)

⚙️ 配置说明

基础配置

配置文件位置:config/lang.php

<?php
return [
    // 默认语言
    'default_lang'    => 'zh-cn',
    
    // 允许的语言列表(必须配置)
    'allow_lang_list' => ['zh-cn', 'en-us'],
    
    // 转义为对应语言包名称(lang 映射关系)
    'accept_language' => [
        'en'         => 'en-us',      // URL 参数 ?lang=en 映射到 en-us
        'zh-hans-cn' => 'zh-cn',      // 浏览器语言 zh-hans-cn 映射到 zh-cn
    ],
    
    // 多语言自动侦测变量名(URL 参数名)
    'detect_var'      => 'lang',
    
    // 多语言 Cookie 变量
    'cookie_var'      => 'lang',
    
    // 多语言 Header 变量
    'header_var'      => 'lang',
    
    // 使用 Cookie 记录
    'use_cookie'      => true,
    
    // 是否支持语言分组
    'allow_group'     => false,
    
    // 扩展语言包
    'extend_list'     => [],
];

配置说明

  • default_lang:系统默认语言,当无法检测到语言时使用
  • allow_lang_list:允许的语言列表,只有列表中的语言才会被使用
    • 注意:如果要支持英文,需要在此列表中添加 'en-us'
    • 示例:['zh-cn', 'en-us'] 表示支持中文和英文
  • accept_language:lang 映射关系,将 URL 参数或浏览器语言映射到实际的语言包名称
    • 例如:?lang=en 会映射到 en-us
    • 例如:浏览器语言 zh-hans-cn 会映射到 zh-cn
    • 映射后的语言必须在 allow_lang_list 中才会生效
  • detect_var:URL 参数变量名,默认为 lang,可通过 ?lang=en 切换语言
  • use_cookie:是否使用 Cookie 记录用户选择的语言

语言切换方式

  1. URL 参数切换(最高优先级)

    • 访问:http://domain.com/admin/index?lang=en
    • 系统会根据 accept_language 映射关系将 en 转换为 en-us
    • 如果映射后的 en-us 不在 allow_lang_list 中,则使用默认语言
  2. 浏览器语言检测(次优先级)

    • 如果没有 URL 参数,系统会检测浏览器的 Accept-Language
    • 根据 accept_language 映射关系将浏览器语言转换为对应的语言包名称
    • 如果映射后的语言不在 allow_lang_list 中,则使用默认语言
  3. Cookie 记录(如果启用)

    • 用户选择的语言会保存在 Cookie 中
    • 下次访问时会自动使用 Cookie 中的语言设置
  4. 默认语言(最后回退)

    • 如果以上方式都无法确定语言,则使用 default_lang 配置的语言

语言包文件

  • 应用语言包: app/模块名/lang/LANG.php(如 app/admin/lang/zh-cn.phpapp/admin/lang/en-us.php
    • 注意:应用语言包必须在模块目录下,不支持项目根目录的 app/lang/ 目录
  • 动态语言包: 数据字典存储
  • 文件格式: 支持 PHP 数组格式
  • 编码要求: 建议使用 UTF-8 编码

性能优化

  • 缓存机制: 语言包自动缓存减少文件读取
  • 懒加载: 按需加载语言包内容
  • 内存优化: 优化语言包内存使用
  • 文件监控: 支持语言包文件变更监控

📱 应用语言包

应用语言包仅在当前应用有效,适合定义应用特定的业务文本。

📝 创建方法

文件位置app/模块名/lang/ 目录下(如 app/admin/lang/app/index/lang/

重要提示:应用语言包必须在模块目录下,不支持项目根目录的 app/lang/ 目录。

文件命名规则:文件名称必须与语言代码一致

创建步骤

步骤1:创建语言包目录

# 为 admin 应用创建语言包目录
mkdir -p app/admin/lang

# 创建中文语言包
touch app/admin/lang/zh-cn.php

# 创建英文语言包
touch app/admin/lang/en-us.php

步骤2:编写语言包内容

方式一:静态语言包(简单场景)

<?php
// app/admin/lang/zh-cn.php
// 后台管理应用的中文语言包

return [
    // 用户管理相关
    'user_management' => '用户管理',
    'add_user' => '添加用户',
    'edit_user' => '编辑用户',
    'delete_user' => '删除用户',
    'user_list' => '用户列表',
    'user_detail' => '用户详情',
    
    // 权限管理相关
    'permission_management' => '权限管理',
    'role_management' => '角色管理',
    'menu_management' => '菜单管理',
    
    // 系统配置相关
    'system_config' => '系统配置',
    'site_config' => '站点配置',
    'email_config' => '邮件配置',
];

方式二:动态语言包(参考 think-library/src/lang/en-us.php)

可以参考 think-library/src/lang/en-us.php 的实现方式,在应用语言包中从数据字典动态读取翻译:

<?php
// app/admin/lang/en-us.php
// 后台管理应用的英文语言包(支持从数据字典动态读取)

use think\admin\model\SystemBase;

// 从数据字典读取英文字典(已有类型,直接使用)
$customLangs = [];
if (count($items = SystemBase::items('英文字典')) > 0) {
    $customLangs = array_column($items, 'name', 'code');
}

// 合并静态翻译和动态翻译
return array_merge([
    // 静态翻译内容
    'user_management' => 'User Management',
    'add_user' => 'Add User',
    'edit_user' => 'Edit User',
    'delete_user' => 'Delete User',
    'user_list' => 'User List',
    'user_detail' => 'User Detail',
    
    // 权限管理相关
    'permission_management' => 'Permission Management',
    'role_management' => 'Role Management',
    'menu_management' => 'Menu Management',
    
    // 系统配置相关
    'system_config' => 'System Config',
    'site_config' => 'Site Config',
    'email_config' => 'Email Config',
], $customLangs);  // 合并从数据字典读取的翻译(包括字典和菜单)

提示:参考 think-library/src/lang/en-us.php 的实现,可以在语言包文件中:

  • 从数据字典读取翻译内容
  • 合并静态翻译和动态翻译
  • 支持缓存优化(参考原文件中的缓存实现)

步骤3:在应用中使用

<?php
// app/admin/controller/User.php
namespace app\admin\controller;

use think\admin\Controller;

class User extends Controller
{
    public function index()
    {
        // 使用应用语言包
        $this->title = lang('user_management');  // 输出:用户管理(中文)或 User Management(英文)
        
        // 在模板中也会自动使用应用语言包
        return $this->fetch();
    }
}

🔄 多应用对比

不同应用可以有相同的语言键,但显示不同的文本:

<?php
// app/admin/lang/zh-cn.php(后台管理)
return [
    'user_center' => '用户管理中心',
    'user_list' => '用户列表',
];

// app/index/lang/zh-cn.php(前台应用)
return [
    'user_center' => '个人中心',  // 相同的键,不同的值
    'user_list' => '我的信息',
];

使用效果

<?php
// 在 admin 应用中
echo lang('user_center');  // 输出:用户管理中心

// 在 index 应用中
echo lang('user_center');  // 输出:个人中心(不同的文本)

🔄 动态语言包

动态语言包存储在数据库中,可以通过后台管理界面编辑,无需修改代码文件。这种方式的优势是可以实时修改语言包内容,无需重启系统。

🤔 基本概念

静态语言包 vs 动态语言包

对比项静态语言包(文件)动态语言包(数据库)
存储位置文件系统数据库
修改方式修改 PHP 文件后台界面编辑
生效方式需要重启或清理缓存立即生效
适用场景固定的系统文本需要频繁修改的文本
性能较快(文件缓存)稍慢(需要查询数据库)

📦 内置语言包

ThinkAdmin 已内置两个动态语言包,可以直接使用:

1. 英文字典

用于将中文翻译为英文,存储在数据字典表中。

查看方式

<?php
// 在后台数据字典中查看
// 系统管理 → 数据字典 → 查找 type = '英文字典'

数据结构

type: '英文字典'
code: '欢迎使用'        // 中文原文(作为键)
name: 'Welcome'         // 英文翻译(作为值)

使用方式

<?php
// 在英文语言包中,英文字典会自动合并到语言包中
// 直接使用中文原文作为键即可
echo lang('欢迎使用');  // 输出:Welcome(从数据字典读取)

// 实际应用:将中文菜单翻译为英文
$menu = '用户管理';
$menuEn = lang($menu);  // 从数据字典查找翻译

2. 英文菜单

专门用于系统后台菜单的英文翻译,这是为后台管理系统菜单设计的多语言支持。

查看方式

<?php
// 在后台数据字典中查看
// 系统管理 → 数据字典 → 查找 type = '英文菜单'

数据结构

type: '英文菜单'
code: 'admin/user/index'     // 后台菜单节点(作为键)
name: 'User Management'       // 英文翻译(作为值)

使用方式

<?php
// 在英文语言包文件中,英文菜单会自动合并到语言包中
// 使用 menus_ 前缀访问菜单翻译
// 这是专门用于后台管理系统菜单的翻译
echo lang('menus_admin/user/index');  // 输出:User Management

// 注意:英文菜单数据会自动从数据字典读取并合并到语言包中
// 在 think-library/src/lang/en-us.php 文件中可以看到相关实现
// 系统会将 code 作为键,name 作为值,并添加 menus_ 前缀
// 这些翻译专门用于后台管理系统的菜单栏显示(如左侧导航菜单、顶部菜单等)

技术说明

  • 英文菜单数据存储在数据字典表中,type 为 英文菜单
  • 在英文语言包文件(en-us.php)中,系统会自动从数据字典读取英文菜单数据
  • 菜单翻译使用 menus_ 前缀,方便与普通翻译区分
  • 专门用于后台管理系统菜单:这是为后台界面的菜单栏(如左侧导航菜单、顶部菜单等)设计的多语言支持
  • 该文件仅在英文模式下才会加载,系统默认使用中文模式

🛠️ 自定义动态语言包(完整示例)

ThinkAdmin 支持通过数据字典创建自定义动态语言包,可以轻松支持更多语言(英文、日文、韩文、法文、德文、西班牙文等)。

多语言对应关系

语言包文件字典类型菜单类型说明
en-us.php英文字典英文菜单英文语言包对应类型(已有类型,无需新建)
ja-jp.php日文字典日文菜单日文语言包对应类型(需创建)
ko-kr.php韩文字典韩文菜单韩文语言包对应类型(需创建)
fr-fr.php法文字典法文菜单法文语言包对应类型(需创建)
de-de.php德文字典德文菜单德文语言包对应类型(需创建)
es-es.php西班牙文字典西班牙文菜单西班牙文语言包对应类型(需创建)
其他语言[语言名]字典[语言名]菜单依此类推,支持任意语言

说明

  • 字典类型:用于普通文本翻译,如 英文字典日文字典 等,用于页面内容、提示信息等普通文本的多语言支持
  • 菜单类型专门用于系统后台菜单翻译,如 英文菜单日文菜单 等,使用 menus_ 前缀访问,这是为后台管理系统的菜单栏设计的多语言支持
  • 已有类型英文字典英文菜单 是系统内置类型,无需创建,直接使用即可
  • 其他语言:需要创建对应的字典类型和菜单类型,命名规则为 [语言名]字典[语言名]菜单

📌 重要区别

  • 字典类型:用于页面内容、提示信息、按钮文字等普通文本的翻译
  • 菜单类型专门用于系统后台菜单栏的翻译,如左侧导航菜单、顶部菜单等后台界面菜单

⚠️ 同步配置要求

  • 字典和菜单必须同时配置,不能只配置其中一个
  • 如果只配置字典,菜单会显示不完整(显示为中文或语言键)
  • 如果只配置菜单,普通文本会显示不完整(显示为中文或语言键)
  • 只有同时配置字典和菜单,后台切换语言时才能完整显示

完整示例:英文语言包

步骤1:在语言包文件中读取数据字典

<?php
// app/admin/lang/en-us.php(英文语言包)
use think\admin\Library;
use think\admin\model\SystemBase;

// 动态读取英文字典数据字典(带缓存优化)
if (count($customLangs = Library::$sapp->cache->get('lang-custom-en', [])) < 1) {
    // 从数据字典读取英文字典(已有类型,直接使用)
    $customLangs = array_column(SystemBase::items('英文字典'), 'name', 'code');
    
    // 从数据字典读取英文菜单(已有类型,直接使用)
    $menus = array_column(SystemBase::items('英文菜单'), 'name', 'code');
    foreach ($menus as $key => $name) {
        $customLangs["menus_{$key}"] = $name;
    }
    
    Library::$sapp->cache->set('lang-custom-en', $customLangs, 360);
}

// 合并静态翻译和动态翻译
return array_merge([
    // 静态翻译内容
    'welcome' => 'Welcome',
    'login_success' => 'Login Success',
    // ... 其他静态翻译
], $customLangs);  // 合并从数据字典读取的翻译(包括字典和菜单)

步骤2:在数据字典中添加数据

通过后台系统管理界面添加:

  1. 进入:系统管理数据字典
  2. 添加数据:
    • type: 英文字典(数据字典类型,已有类型,与英文语言包 en-us.php 对应)
    • code: welcome(作为语言键)
    • name: Welcome to Our System(翻译内容)

数据示例

type: '英文字典'
code: 'welcome'
name: 'Welcome to Our System'

type: '英文字典'
code: 'login'
name: 'Please Login'

步骤3:在代码中使用

<?php
// 直接使用数据字典中的 code 作为语言键
echo lang('welcome');  // 输出:Welcome to Our System(从数据字典读取)
echo lang('login');     // 输出:Please Login(从数据字典读取)

// 如果找不到对应的翻译,会先回退到中文语言包查找
// 如果中文语言包中也找不到,才会返回语言键本身
echo lang('not_found');  // 先查找 en-us.php,找不到则查找 zh-cn.php,都找不到则返回 'not_found'

步骤4:在后台管理语言包

管理员可以通过后台界面随时修改语言包内容,修改后需要清理缓存才能生效:

  1. 进入:系统管理数据字典
  2. 筛选:type = '英文字典'type = '英文菜单'(已有类型,直接使用)
    • 注意:需要同时管理字典和菜单两种类型的数据
  3. 编辑:修改 name 字段(翻译内容)
  4. 保存:修改后需要清理缓存(php think clear 或删除 runtime/cache 目录)

⚠️ 重要:修改语言包时,必须同时检查字典和菜单两种类型的数据,确保两者都已正确配置,否则语言切换会不完整。

添加新语言支持

要添加新语言支持(如日文、韩文等),只需:

  1. 创建语言包文件app/admin/lang/ja-jp.php(日文示例)
  2. 在数据字典中创建类型必须同时创建 日文字典日文菜单 类型(如果不存在)
  3. 在语言包文件中读取数据字典必须同时读取 SystemBase::items('日文字典')SystemBase::items('日文菜单')
  4. 在数据字典中添加数据必须同时添加,type 设置为 日文字典日文菜单
  5. config/lang.php 中配置:将新语言添加到 allow_lang_list

⚠️ 重要提醒字典和菜单必须同步配置,否则后台切换语言时会显示不完整。建议:

  • 先创建字典类型和菜单类型
  • 在语言包文件中同时读取字典和菜单
  • 在数据字典中同时添加字典和菜单数据
  • 测试时确保两种类型的数据都已正确配置

提示

  • 语言包文件应放在 app/admin/lang/en-us.php(应用语言包),这样可以在 admin 模块中使用。
  • 数据字典类型必须与语言包文件对应:英文语言包读取"英文字典"和"英文菜单"(已有类型),其他语言包读取对应的"XX字典"和"XX菜单"类型(如"日文字典"、"日文菜单"、"韩文字典"、"韩文菜单"等)。
  • ThinkAdmin 可以支持任意语言,只需创建对应的语言包文件和数据字典类型即可。

✨ 优势说明

实时修改

  • 修改语言包无需修改代码文件
  • 修改后立即生效,无需重启系统
  • 适合需要频繁修改的场景

多用户协作

  • 翻译人员可以通过后台直接编辑
  • 不需要访问代码文件
  • 降低操作门槛

灵活管理

  • 可以按类型分类管理
  • 支持批量导入导出
  • 便于版本控制

实际应用场景

  • ✅ 需要频繁修改的菜单文本
  • ✅ 用户自定义的文本标签
  • ✅ 需要后期修补的语言包
  • ✅ 多语言协作翻译的场景

💻 代码使用

🎮 控制器使用

ThinkAdmin 提供了两种方式获取语言包:lang() 函数和 Lang::get() 方法。

方式1:使用 lang() 函数(推荐)

lang() 是 ThinkAdmin 提供的全局函数,使用最简单。

函数签名

lang(string $name, array $vars = [], string $lang = '')

参数说明

  • $name:语言变量名(必需),如 'welcome''menu.user'
  • $vars:动态变量值(可选,默认空数组),用于替换语言包中的占位符,如 ['name' => '张三']
  • $lang:指定语言(可选,默认空字符串),如 'en-us''zh-cn' 等。如果为空,则使用当前语言

回退机制

  • 当调用 lang('key') 时,系统会按以下顺序查找翻译:
    1. 首先查找当前语言的语言包文件(如 app/admin/lang/en-us.php
    2. 如果当前语言包中找不到,自动回退到中文语言包(app/admin/lang/zh-cn.php)查找
    3. 如果中文语言包中也找不到,才会返回语言键本身
  • 这样可以确保即使某些语言包不完整,也能显示中文内容,提升用户体验
  • 建议:优先使用中文作为默认语言,确保中文语言包完整
<?php
declare(strict_types=1);

namespace app\admin\controller;

use think\admin\Controller;

class Example extends Controller
{
    public function index()
    {
        // 基本用法:获取语言包
        $message = lang('welcome');
        // 如果当前语言是中文,输出:欢迎使用
        // 如果当前语言是英文,输出:Welcome
        
        // 指定语言:强制使用指定语言
        $messageEn = lang('welcome', [], 'en-us');
        // 无论当前语言是什么,都返回英文翻译
        
        // 带参数:使用占位符替换
        $info = lang('welcome_user', ['name' => '张三']);
        // 语言包定义:'welcome_user' => '欢迎,{name}!'
        // 输出:欢迎,张三!
        
        // 指定语言并带参数
        $infoEn = lang('welcome_user', ['name' => 'John'], 'en-us');
        // 输出:Welcome, John!
        
        // 回退机制说明:
        // 1. 系统会先查找当前语言的语言包文件(如 app/admin/lang/en-us.php)
        // 2. 如果当前语言包中找不到翻译,会自动回退到中文语言包(app/admin/lang/zh-cn.php)查找
        // 3. 如果中文语言包中也找不到,才会返回语言键本身
        // 这样可以确保即使某些语言包不完整,也能显示中文内容
        
        // 传递给模板
        $this->assign([
            'message' => $message,
            'messageEn' => $messageEn,
            'info' => $info,
            'infoEn' => $infoEn,
        ]);
        
        return $this->fetch();
    }
}

方式2:使用 Lang::get() 方法

Lang::get() 是 ThinkPHP 提供的方法,功能更强大:

<?php
declare(strict_types=1);

namespace app\admin\controller;

use think\admin\Controller;
use think\facade\Lang;

class Example extends Controller
{
    public function index()
    {
        // 基本用法
        $message = Lang::get('welcome');
        
        // 指定语言:强制使用指定语言
        $messageEn = Lang::get('welcome', [], 'en-us');
        // 无论当前语言是什么,都返回英文翻译
        
        // 带参数
        $info = Lang::get('welcome_user', ['name' => 'John'], 'en-us');
        
        // 带默认值
        $title = Lang::get('page_title', [], 'zh-cn', '默认标题');
        
        return $this->fetch();
    }
}

两种方式对比

特性lang() 函数Lang::get() 方法
使用简单✅ 更简单(全局函数,无需 use)⚠️ 需要 use
指定语言✅ 支持(第三个参数)✅ 支持
参数替换✅ 支持(第二个参数)✅ 支持
推荐场景一般使用(推荐)需要类型提示或 IDE 支持时

📄 模板使用

在模板中使用语言包有两种方式:函数调用和过滤器。

方式1:使用 lang() 函数

<!-- 基本用法 -->
<h1>{:lang('welcome')}</h1>
<!-- 输出:欢迎使用(中文)或 Welcome(英文) -->

<!-- 带参数 -->
<p>{:lang('welcome_user', ['name' => $user['name']])}</p>
<!-- 语言包:'welcome_user' => '欢迎,{name}!' -->
<!-- 输出:欢迎,张三! -->

<!-- 指定语言 -->
<p>{:lang('welcome', [], 'en-us')}</p>
<!-- 输出:Welcome(强制使用英文) -->

方式2:使用 |lang 过滤器

<!-- 使用过滤器 -->
<p>{$title|lang}</p>
<!-- $title 变量值作为语言键,自动查找翻译 -->

<!-- 实际应用 -->
{assign name="menu_key" value="user_management"}
<p>{$menu_key|lang}</p>
<!-- 输出:用户管理(中文)或 User Management(英文) -->

完整模板示例

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>{:lang('system_name')}</title>
</head>
<body>
    <h1>{:lang('welcome')}</h1>
    
    <div class="user-info">
        <p>{:lang('welcome_user', ['name' => $user['name']])}</p>
        <p>{:lang('user_count', ['count' => $userCount])}</p>
    </div>
    
    <div class="actions">
        <button>{:lang('button_save')}</button>
        <button>{:lang('button_cancel')}</button>
    </div>
</body>
</html>

📋 文件格式

语言包文件必须返回一个关联数组,支持多种格式:

格式1:简单键值对

<?php
// app/admin/lang/zh-cn.php
return [
    'welcome' => '欢迎使用',
    'login_success' => '登录成功',
    'button_save' => '保存',
];

格式2:带参数的语言包(使用占位符)

<?php
// app/admin/lang/zh-cn.php
return [
    // 单个参数
    'welcome_user' => '欢迎,{name}!',
    
    // 多个参数
    'user_count' => '共有 {count} 个用户,其中 {active} 个活跃用户',
    
    // 实际使用
    // lang('welcome_user', ['name' => '张三'])
    // 输出:欢迎,张三!
    
    // lang('user_count', ['count' => 100, 'active' => 80])
    // 输出:共有 100 个用户,其中 80 个活跃用户
];

格式3:嵌套数组(支持多级)

<?php
// app/admin/lang/zh-cn.php
return [
    // 一级键
    'menu' => [
        'user' => '用户管理',
        'role' => '角色管理',
        'permission' => '权限管理',
    ],
    
    'button' => [
        'save' => '保存',
        'cancel' => '取消',
        'delete' => '删除',
    ],
];

// 使用嵌套语言包
// lang('menu.user')        // 输出:用户管理
// lang('button.save')      // 输出:保存
// lang('menu.role')         // 输出:角色管理

格式4:混合格式

<?php
// app/admin/lang/zh-cn.php
return [
    // 简单键值对
    'welcome' => '欢迎使用',
    
    // 带参数
    'welcome_user' => '欢迎,{name}!',
    
    // 嵌套数组
    'menu' => [
        'user' => '用户管理',
        'role' => '角色管理',
    ],
    
    // 嵌套数组中也支持参数
    'message' => [
        'user_added' => '用户 {name} 已添加',
        'user_deleted' => '用户 {name} 已删除',
    ],
];

// 使用示例
// lang('welcome')                           // 输出:欢迎使用
// lang('welcome_user', ['name' => '张三'])  // 输出:欢迎,张三!
// lang('menu.user')                         // 输出:用户管理
// lang('message.user_added', ['name' => '李四'])  // 输出:用户 李四 已添加

🔄 参数替换

语言包支持使用占位符,在调用时传入参数进行替换。

占位符格式

  • 使用花括号 {参数名} 作为占位符
  • 参数名可以是任意字符串
  • 支持多个参数

定义语言包

<?php
// app/admin/lang/zh-cn.php
return [
    // 单个参数
    'welcome_user' => '欢迎,{name}!',
    
    // 多个参数
    'user_info' => '用户 {name},年龄 {age} 岁,来自 {city}',
    
    // 参数可以重复使用
    'user_message' => '{name} 给 {name} 发送了消息',
];

使用示例

<?php
// 单个参数
echo lang('welcome_user', ['name' => '张三']);
// 输出:欢迎,张三!

// 多个参数
echo lang('user_info', [
    'name' => '李四',
    'age' => 25,
    'city' => '北京'
]);
// 输出:用户 李四,年龄 25 岁,来自 北京

// 参数重复使用
echo lang('user_message', ['name' => '王五']);
// 输出:王五 给 王五 发送了消息

在模板中使用参数

<!-- 带参数的语言包 -->
<p>{:lang('welcome_user', ['name' => $user['name']])}</p>

<!-- 多个参数 -->
<p>{:lang('user_info', [
    'name' => $user['name'],
    'age' => $user['age'],
    'city' => $user['city']
])}</p>

🔀 切换机制

如何切换语言?

方式1:后台系统配置

  1. 登录后台管理系统
  2. 进入:系统管理系统参数配置
  3. 找到:默认语言 配置项
  4. 选择语言:zh-cn(中文)或 en-us(英文)
  5. 点击:保存

方式2:代码切换

<?php
// 在控制器中切换语言
use think\facade\Lang;

// 切换到英文
Lang::setLangSet('en-us');

// 切换到中文
Lang::setLangSet('zh-cn');

方式3:URL 参数切换(推荐)

通过 URL 参数 ?lang=en 可以快速切换语言,系统会自动处理:

<?php
// 访问:http://domain.com/admin/index?lang=en
// 系统会自动:
// 1. 读取 URL 参数 lang=en
// 2. 根据 config/lang.php 中的 accept_language 映射关系
//    将 'en' 映射到 'en-us'
// 3. 检查 'en-us' 是否在 allow_lang_list 中
// 4. 如果允许,则切换到 en-us 语言包
// 5. 如果启用 use_cookie,会保存到 Cookie 中

// 无需在控制器中手动处理,系统会自动切换
public function index()
{
    // 系统已自动切换语言,直接使用即可
    echo lang('welcome');  // 根据当前语言显示对应文本
}

浏览器语言检测

如果没有 URL 参数,系统会使用浏览器语言:

<?php
// 用户浏览器语言为 en-US
// 系统会自动:
// 1. 检测浏览器 Accept-Language 头
// 2. 根据 accept_language 映射关系将浏览器语言转换为对应的语言包名称(如 en-US 映射到 en-us)
// 3. 如果映射后的语言不在 allow_lang_list 中,使用默认语言

语言优先级

  1. URL 参数(最高优先级):?lang=en
  2. Cookie 记录(如果启用 use_cookie
  3. 浏览器语言检测:根据浏览器 Accept-Language
  4. 系统默认配置default_lang

❓ 常见问题

Q1:语言包不生效?

可能原因

  • 语言包文件不存在
  • 文件命名不正确
  • 缓存未清理

解决方法

# 1. 检查语言包文件是否存在
ls -la app/admin/lang/zh-cn.php

# 2. 检查文件命名是否正确(必须与语言代码一致)
# 正确:zh-cn.php
# 错误:zh_cn.php、zhcn.php

# 3. 清理缓存
php think clear
# 或
rm -rf runtime/cache/*

Q2:如何添加新语言?

步骤

  1. 创建语言包文件:app/admin/lang/ja-jp.php(日文示例)
  2. 编写翻译内容
  3. 在系统配置中添加语言选项
  4. 用户可以选择新语言

示例

<?php
// app/admin/lang/ja-jp.php
return [
    'welcome' => 'ようこそ',
    'login_success' => 'ログイン成功',
];

Q3:语言包支持嵌套多少层?

理论上支持无限层嵌套,但建议不超过 3 层,保持结构清晰:

<?php
// 支持但不推荐:嵌套过深
return [
    'level1' => [
        'level2' => [
            'level3' => [
                'level4' => '值'  // 不推荐
            ]
        ]
    ]
];

// 推荐:保持 2-3 层
return [
    'menu' => [
        'user' => '用户管理',  // 2 层,推荐
    ],
];
最近更新:
Contributors: 邹景立, Anyon