laravel 语言包

康赞
2023-12-01

laravel 语言包


基于Laravel-Lang/Lang的75种语言支持Laravel 5的应用。

1. 安装

GitHub overtrue/laravel-lang

readme.md 详细介绍了安装方法以及如何使用

laravel 6.x 安装方式

composer require overtrue/laravel-lang:~4.0

laravel 7.x - 8.x

composer require overtrue/laravel-lang:~5.0

2. 配置

配置默认语言, 配置文件 config/app.php

'locale' => 'zh_CN',

3. 使用

快速导出一种或者多种语言. 如果是多种语言, 语言之间用 , 隔开

php artisan lang:publish zh_CN,zh_HK,th,tk

语言包位置: resource/{language}, 可以在此目录下自定义文件, 如: user.php, 文件返回一个关联数组

<?php

return [
    "USER_NAME_EXIST" => "用户名已存在",

    "USER_NAME_OR_PASSWORD_NOT_RIGHT" => "用户名或者密码不正确",

    "USER_PASSWORD_NOT_SAME" => "两次输入密码不一致",
];

使用辅助函数 trans() 获取指定 key 的语言

trans('auth.failed', [], $request->getLocale())

auth 表示 auth.php, failed 表示数组索引

4. 语言动态设置

4.1 客户端语言设置

客户端通过设置 HTTP 头部的 Accept-Language 字段来定于期望的语言

Accept-Language: fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5

语言之间通过, 分割,语言与权重之间通过 ; 隔开

q=0.9 表示权重, 值越大, 表示优先级越高, 通常按照优先级从高到底的顺序

4.2 动态获取语言

Request 提供了 hasHeader() 方法来判断请求头部是否包含指定字段

Request 提供了 getLanguages() 方法来获取客服端期望的语言, 该方法返回数组

$default_language = "zh-CN";
# 假设我们支持的语言包括 "zh-CN", "en"
$support_language = ["zh-CN", "en"];

if ($request->hasHeader('Accept-Language')) {

	$expect_languages = $request->getLanguages();

	foreach ($expect_languages as $key => $value) {

		if (in_array($value, $support_language)) {
			$default_language = $value;
		}

	}
}

getLanguages() 只是安装Accept-Language中配置的语言顺序, 并不会根据权重对语言进行排序, 所以最好按照权重从高到低的顺序设置

4.3 动态设置语言

Request 提供了 setLocale() 方法来设置默认语言

$request->setLocale($default_language);

5. 总结

动态获取和设置的逻辑可以通过前置中间件来配置

5.1 创建中间件

创建 Language 中间件,文件位置: app/Http/Middleware/Language.php

php artisan make:middle Language

中间件 handle() 内容如下

public function handle($request, Closure $next)
{
    $default_language = "zh-CN";
    $support_language = ["zh-CN", "en"];

    if ($request->hasHeader('Accept-Language')) {

        $expect_languages = $request->getLanguages();

        foreach ($expect_languages as $key => $value) {

            if (in_array($value, $support_language)) {
                $default_language = $value;
            }

        }
    }

    $request->setLocale($default_language);

    return $next($request);
}

5.2 注册中间件

文件: app/Http/Kernel.php, 添加到 $routeMiddleware 数组即可

    protected $routeMiddleware = [
        //..
        'language' => \App\Http\Middleware\Language::class,
    ];

5.3 使用中间件

在路由中使用 routes/web.php

Route::get('/test/language', 'TestController@language')->middleware('language');

6. 源码阅读

文档 Demo 代码如下

trans('demo.user_not_exists');

原本以为 trans() 会自己获取 locale , 然而并非如此; trans() 定义如下

function trans($key = null, $replace = [], $locale = null)
{
    if (is_null($key)) {
        return app('translator');
    }

    return app('translator')->get($key, $replace, $locale);
}

$locale 默认值是 null, 所以需要获取并传入 locale

trans('auth.failed', [], $request->getLocale()),

$replace 顾名思义, 替换, trans() 支持变量替换, 如

trans('email.email_has_registed', ['email' => 'anzhengchao@gmail.com'], $request->getLocale()),

如何在语言包中使用$replace ? 通过 : + 数组索引的方式

return [
    'email_has_registed' => '邮箱 :email 已经注册过!',
];
 类似资料: