一 开启配置
1 开启多语言
配置config/lang.php,这里给中英示例
<?php
// +----------------------------------------------------------------------
// | 多语言设置
// +----------------------------------------------------------------------
return [
// 默认语言
'default_lang' => env('DEFAULT_LANG', 'zh-cn'),
// 允许的语言列表
'allow_lang_list' => ['zh-cn', 'en-us'],
// 多语言自动侦测变量名
'detect_var' => 'lang',
// 是否使用Cookie记录
'use_cookie' => true,
// 多语言cookie变量
'cookie_var' => 'think_lang',
// 多语言header变量
'header_var' => 'think-lang',
// 扩展语言包
'extend_list' => [
'zh-cn' => [
app()->getBasePath() . 'lang/zh-cn.php',
],
'en-us' => [
app()->getBasePath() . 'lang/en-us.php',
],
],
// Accept-Language转义为对应语言包名称
'accept_language' => [
'zh-cn' => 'zh-cn',
'en-us' => 'en-us'
],
// 是否支持语言分组
'allow_group' => true,
];
2 新增语言包
新增在上述配置的extend_list中,指向的语言包
- 根目录下新增lang文件夹
- 新增zh-cn.php和en-us.php
新增的语言包格式为
<?php
return [
'api'=>[
'test'=>[
'hello'=>'你好'
]
],
'admin'=>[
],
'shop'=>[
],
'device'=>[
]
];
注意:ThinkPHP 最多可支持多语言分组两层目录,再往下识别不到,需要自定义修改源码
3 支持自动切换
需要在app/middleware.php下开启多语言自动侦测及自动切换
<?php
// 全局中间件定义文件
return [
// 多语言加载
\think\middleware\LoadLangPack::class,
];
二 语言分组可三级以上
1 修改Lang源码
在tp8中的路径为vendor/topthink/framework/src/think/Lang.php
/**
* 判断是否存在语言定义(不区分大小写)
* @access public
* @param string $name 语言变量
* @param string $range 语言作用域
* @return bool
*/
public function has(string $name, string $range = ''): bool
{
$range = $range ?: $this->range;
if ($this->config['allow_group'] && strpos($name, '.')) {
$names = explode('.', $name);
$i = 0;
$temp = $this->lang[$range];
foreach ($names as $key) {
if(!isset($temp[strtolower($key)])) return false;
$temp = $temp[strtolower($key)];
$i++;
}
return is_string($temp);
}
return isset($this->lang[$range][strtolower($name)]);
}
/**
* 获取语言定义(不区分大小写)
* @access public
* @param string|null $name 语言变量
* @param array $vars 变量替换
* @param string $range 语言作用域
* @return mixed
*/
public function get(string $name = null, array $vars = [], string $range = '')
{
$range = $range ?: $this->range;
// 空参数返回所有定义
if (is_null($name)) {
return $this->lang[$range] ?? [];
}
if ($this->config['allow_group'] && strpos($name, '.')) {
$names = explode('.', $name);
$i = 0;
$temp = $this->lang[$range];
foreach ($names as $key) {
if(!isset($temp[strtolower($key)])) {
$temp = $name;
break;
}
$temp = $temp[strtolower($key)];
if($i > sizeof($names)) break;
$i++;
}
$value = is_string($temp) ? $temp : $name;
} else {
$value = $this->lang[$range][strtolower($name)] ?? $name;
}
// 变量解析
if (!empty($vars) && is_array($vars)) {
/**
* Notes:
* 为了检测的方便,数字索引的判断仅仅是参数数组的第一个元素的key为数字0
* 数字索引采用的是系统的 sprintf 函数替换,用法请参考 sprintf 函数
*/
if (key($vars) === 0) {
// 数字索引解析
array_unshift($vars, $value);
$value = call_user_func_array('sprintf', $vars);
} else {
// 关联索引解析
$replace = array_keys($vars);
foreach ($replace as &$v) {
$v = "{:{$v}}";
}
$value = str_replace($replace, $vars, $value);
}
}
return $value;
}
2 实现
public function test(){
return lang('api.test.hello');
}
输出:你好