Laravel 动态本地化

Laravel 动态本地化

多语言的要求越来越普遍,不过框架内置的本地化针对的是固定文件的形式,而有时候我们需要动态添加一些内容,这边是自己的一个实践。为较好的管理采用数据表的方式来对动态内容进行存储。

database\migrations\2021_02_10_000000_create_lang_content_table.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateLangContentTable extends Migration
{
protected $table = 'lang_content';

/**
* Run the migrations.
*
* @return void
*/
public function up()
{
if(Schema::hasTable($this->table)) {
return true;
}

Schema::create($this->table, function (Blueprint $table) {
$table->id();
$table->string('lang', 6)->index()->comment('语言');
$table->string('group', 20)->index()->default('trends')->comment('组'); // 每一条都需要有一个组(或者理解分类),以符合框架追加。
$table->string('key', 200)->index()->comment('键值');
$table->string('value', 2000)->comment('值');
$table->timestamps();
});

\DB::statement("ALTER TABLE `$this->table` comment '语言内容表'");
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists($this->table);
}
}

app\Models\LangContent.php

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class LangContent extends Model
{
use HasFactory;

protected $table = 'lang_content';
}

app\Providers\AppServiceProvider.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<?php

namespace App\Providers;

use App\Models\LangContent;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}

/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
// 加载动态本地化内容

// 获取当前语言
$locale = app()->getLocale();

try {
// 进行一个缓存避免数据库压力
$list = cache()->remember('localization_' . $locale, now()->addMinutes(10), function () use($locale) {
// 读取数据表
$data = LangContent::select('key', 'value', 'group')->where('lang', $locale)->get();

if($data->isEmpty()) {
return [];
}

$list = [];

foreach($data as $item) {
// 格式转换成 addLines 可以识别的
$list[$item->group . '.' . $item->key] = $item->value;
}

return $list;
});

if(count($list)) {
// 追加框架本地化内容
app('translator')->addLines($list, $locale);
}
} catch (\Exception $e) {
}
}
}

测试,为了方便这边直接手动添加数据到数据库。

1
2
3
$ php artisan tinker
>>> __('trends.hongfs')
=> "新年快乐"
往上