🌐 多语言
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.php、en-us.php)
语言键(Language Key)
- 用于标识文本的唯一标识符
- 格式:字符串,支持点号分隔(如
user.name、menu.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.php、en-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 已内置两个动态语言包:
英文字典
- type:
英文字典 - 用于英文翻译字典
- 存储位置:数据字典表
- 用途:将中文翻译为英文
- type:
英文菜单
- type:
英文菜单 - 专门用于系统后台菜单的英文翻译
- 存储位置:数据字典表
- 用途:后台管理系统的菜单多语言支持
- 注意:这是专门为后台菜单设计的,不是用于普通文本翻译
- 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(翻译内容)
- type:
步骤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 记录用户选择的语言
语言切换方式:
URL 参数切换(最高优先级)
- 访问:
http://domain.com/admin/index?lang=en - 系统会根据
accept_language映射关系将en转换为en-us - 如果映射后的
en-us不在allow_lang_list中,则使用默认语言
- 访问:
浏览器语言检测(次优先级)
- 如果没有 URL 参数,系统会检测浏览器的
Accept-Language头 - 根据
accept_language映射关系将浏览器语言转换为对应的语言包名称 - 如果映射后的语言不在
allow_lang_list中,则使用默认语言
- 如果没有 URL 参数,系统会检测浏览器的
Cookie 记录(如果启用)
- 用户选择的语言会保存在 Cookie 中
- 下次访问时会自动使用 Cookie 中的语言设置
默认语言(最后回退)
- 如果以上方式都无法确定语言,则使用
default_lang配置的语言
- 如果以上方式都无法确定语言,则使用
语言包文件
- 应用语言包:
app/模块名/lang/LANG.php(如app/admin/lang/zh-cn.php、app/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:在数据字典中添加数据
通过后台系统管理界面添加:
- 进入:系统管理 → 数据字典
- 添加数据:
- type:
英文字典(数据字典类型,已有类型,与英文语言包en-us.php对应) - code:
welcome(作为语言键) - name:
Welcome to Our System(翻译内容)
- type:
数据示例:
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:在后台管理语言包
管理员可以通过后台界面随时修改语言包内容,修改后需要清理缓存才能生效:
- 进入:系统管理 → 数据字典
- 筛选:
type = '英文字典'或type = '英文菜单'(已有类型,直接使用)- 注意:需要同时管理字典和菜单两种类型的数据
- 编辑:修改
name字段(翻译内容) - 保存:修改后需要清理缓存(
php think clear或删除runtime/cache目录)
⚠️ 重要:修改语言包时,必须同时检查字典和菜单两种类型的数据,确保两者都已正确配置,否则语言切换会不完整。
添加新语言支持:
要添加新语言支持(如日文、韩文等),只需:
- 创建语言包文件:
app/admin/lang/ja-jp.php(日文示例) - 在数据字典中创建类型:必须同时创建
日文字典和日文菜单类型(如果不存在) - 在语言包文件中读取数据字典:必须同时读取
SystemBase::items('日文字典')和SystemBase::items('日文菜单') - 在数据字典中添加数据:必须同时添加,type 设置为
日文字典和日文菜单 - 在
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')时,系统会按以下顺序查找翻译:- 首先查找当前语言的语言包文件(如
app/admin/lang/en-us.php) - 如果当前语言包中找不到,自动回退到中文语言包(
app/admin/lang/zh-cn.php)查找 - 如果中文语言包中也找不到,才会返回语言键本身
- 首先查找当前语言的语言包文件(如
- 这样可以确保即使某些语言包不完整,也能显示中文内容,提升用户体验
- 建议:优先使用中文作为默认语言,确保中文语言包完整
<?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:后台系统配置
- 登录后台管理系统
- 进入:系统管理 → 系统参数配置
- 找到:默认语言 配置项
- 选择语言:
zh-cn(中文)或en-us(英文) - 点击:保存
方式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 中,使用默认语言语言优先级:
- URL 参数(最高优先级):
?lang=en - Cookie 记录(如果启用
use_cookie) - 浏览器语言检测:根据浏览器
Accept-Language头 - 系统默认配置:
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:如何添加新语言?
步骤:
- 创建语言包文件:
app/admin/lang/ja-jp.php(日文示例) - 编写翻译内容
- 在系统配置中添加语言选项
- 用户可以选择新语言
示例:
<?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 层,推荐
],
];