ThinkPHP8 中的多语言支持。\think\middleware\LoadLangPack.php 好像并不能很好的支持多语言的切换,其中$this->lang->setLangSet($langSet) 和$this->lang->switchLangSet($langset)两个语句并不能实现通过传参的方式切换语言。所以自己搞了一个车轮子。
1.创建应用及目录
php think build index
将在app目录下面创建index应用目录,生产相应的默认文件。
index:.
│ common.php
│ event.php
│ middleware.php #中间件设置
│
├─config
│ lang.php #语言设置
│
├─controller
│ Index.php #语言测试
│
├─lang
│ en-us.php #EN
│ zh-cn.php #中文
│
├─middleware
│ IndexAppLangMiddleware.php #探测lang的中间件
│
├─model
└─view
└─index
index.html #前端显示View
app\index\middleware\IndexAppLangMiddleware.php 语言切换控制中间件
<?php
declare (strict_types = 1);
namespace app\index\middleware;
#use Closure;
use think\facade\App;
use think\facade\Config; #配置读取
use think\facade\Lang; #语言支持与操作
use think\facade\Cookie; #Cookie操作
/**
* 多语言加载
*/
class IndexAppLangMiddleware
{
protected $config; #存放配置
protected $lang; #存放最近一次设置的语言
public function __construct(protected App $app) {
$this->config = config("lang"); #读取语言配置
$this->lang = ''; #$this->config['default_lang']; #初始化默认语言
}
/**
* 处理请求
*
* @param \think\Request $request
* @param \Closure $next
* @return Response
*/
public function handle($request, \Closure $next)
{
// 自动侦测当前语言
$langset = $this->detect($request);
if ($this->lang != $langset) {
$this->lang = $langset; #暂存语言
Lang::setLangSet($this->lang); #切换当前语言
}
$this->saveToCookie($langset); #修改Cookie
return $next($request);
}
/**
* 自动侦测设置获取语言选择
* @access protected
* @param Request $request
* @return string
*/
protected function detect($request): string
{
// 自动侦测设置获取语言选择
$langSet = '';
if ($request->get($this->config['detect_var'])) {
// url中设置了语言变量
$langSet = $request->get($this->config['detect_var']);
} elseif ($request->header($this->config['header_var'])) {
// Header中设置了语言变量
$langSet = $request->header($this->config['header_var']);
} elseif ($request->cookie($this->config['cookie_var'])) {
// Cookie中设置了语言变量
$langSet = $request->cookie($this->config['cookie_var']);
} elseif ($request->server('HTTP_ACCEPT_LANGUAGE')) {
// 自动侦测浏览器语言
$langSet = $request->server('HTTP_ACCEPT_LANGUAGE');
}
if (preg_match('/^([a-z\d\-]+)/i', $langSet, $matches)) {
$langSet = strtolower($matches[1]);
if (isset($this->config['accept_language'][$langSet])) {
$langSet = $this->config['accept_language'][$langSet];
}
} else {
$langSet = $this->config['default_lang']; #未检查到语言切换参数,使用默认语言
}
if (empty($this->config['allow_lang_list']) || in_array($langSet, $this->config['allow_lang_list'])) {
// 合法的语言
//Lang::setLangSet($langSet);
} else {
$langSet = $this->config['default_lang'];
}
return $langSet;
}
/**
* 保存当前语言到Cookie
* @access protected
* @param Cookie $cookie Cookie对象
* @param string $langSet 语言
* @return void
*/
protected function saveToCookie(string $langSet): void
{
if ($this->config['use_cookie']) {
Cookie::forever($this->config['cookie_var'], $langSet);
}
}
}
app\index\config\lang.php 语言配置
<?php
// +----------------------------------------------------------------------
// | index-APP多语言设置
// +----------------------------------------------------------------------
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' => 'index_app_lang',
// 多语言header变量
'header_var' => 'index-app-lang',
// 扩展语言包
'extend_list' => [],
// Accept-Language转义为对应语言包名称
'accept_language' => [
'zh-hans-cn' => 'zh-cn',
],
// 是否支持语言分组
'allow_group' => true,
];
语言列表
app\index\lang\en-us.php
<?php
return [
'welcome' => 'Welcome to our website222',
// 其他英文语言项
];
?>
app\index\lang\zh-cn.php
<?php
return [
'welcome' => '欢迎访问我们的网站',
// 其他中文语言项
];
?>
app\index\controller\Index.php
<?php
declare (strict_types = 1);
namespace app\index\controller;
use think\facade\Lang;
use think\facade\View;
use app\index\middleware\IndexAppLangMiddleware;
class Index
{
protected $middleware = [IndexAppLangMiddleware::class];
public function index()
{
$welcome = Lang::get('welcome');
View::assign('welcome', $welcome);
// 渲染模板并显示
return View::fetch('index');
}
}
app\index\view\index\index.html
<!DOCTYPE html>
<html>
<head>
<title>切换语言</title>
</head>
<body>
<p><?php echo $welcome; ?>, ThinkPHP8</p>
<a href="{:url('index', ['lang'=>'zh-cn'])}">中文</a>
<a href="{:url('index', ['lang'=>'en-us'])}">English</a>
</body>
</html>