You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel项目中不使用lang/*.json文件实现多语言支持?

Laravel 无lang/*.json多语言集成方案(动态管理版)

核心方案:数据库驱动翻译(优先满足动态需求)

完全抛弃lang目录下的json文件,将翻译存储在数据库中,支持后台动态新增语言、修改翻译内容,无需改动代码。

推荐第三方包:spatie/laravel-translation-loader

该包完美兼容Laravel原生翻译体系,自动从数据库加载翻译,同时可兼容lang目录下的PHP数组文件(可选)。

分步实现:

  1. 安装包
composer require spatie/laravel-translation-loader
  1. 发布迁移文件
php artisan vendor:publish --provider="Spatie\TranslationLoader\TranslationLoaderServiceProvider" --tag="migrations"
  1. 运行迁移
    生成language_lines表,存储翻译键、语言标识、翻译内容等字段:
php artisan migrate
  1. 动态管理翻译
    直接通过后台CRUD操作language_lines表:
  • 新增语言:添加locale字段为目标语言(如fr、de)的记录
  • 添加翻译:给指定locale和key赋值text内容
  1. 使用翻译
    依然使用Laravel原生翻译函数,自动从数据库读取:
// 视图中
@lang('welcome.greeting')

// 控制器/模型中
__('welcome.greeting')

自定义实现(无第三方包)

若不想依赖第三方包,可自行实现Laravel的TranslationLoaderInterface,完全控制翻译加载逻辑。

1. 创建数据库表

生成translations表迁移:

php artisan make:migration create_translations_table

迁移文件内容:

public function up()
{
    Schema::create('translations', function (Blueprint $table) {
        $table->id();
        $table->string('key'); // 翻译键名,如welcome.greeting
        $table->string('locale'); // 语言标识,如zh-CN、en
        $table->text('value'); // 翻译内容
        $table->string('namespace')->nullable(); // 命名空间,可选
        $table->timestamps();
        $table->unique(['key', 'locale', 'namespace']);
    });
}

运行迁移:

php artisan migrate

2. 创建翻译模型

// app/Models/Translation.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Translation extends Model
{
    protected $fillable = ['key', 'locale', 'value', 'namespace'];
}

3. 实现自定义翻译加载器

// app/Translation/DatabaseTranslationLoader.php
namespace App\Translation;

use Illuminate\Contracts\Translation\Loader;
use App\Models\Translation;
use Illuminate\Support\Facades\Cache;

class DatabaseTranslationLoader implements Loader
{
    protected $model;

    public function __construct(Translation $model)
    {
        $this->model = $model;
    }

    public function load($locale, $group, $namespace = null)
    {
        // 缓存翻译,减少数据库查询
        $cacheKey = "translations_{$locale}_{$group}_{$namespace}";
        return Cache::remember($cacheKey, now()->addDays(7), function () use ($locale, $namespace) {
            $query = $this->model->where('locale', $locale);
            if ($namespace) {
                $query->where('namespace', $namespace);
            }
            return $query->pluck('value', 'key')->toArray();
        });
    }

    public function addLines(array $lines, $locale, $group = '*', $namespace = null)
    {
        foreach ($lines as $key => $value) {
            $this->model->updateOrCreate(
                ['key' => $key, 'locale' => $locale, 'namespace' => $namespace],
                ['value' => $value]
            );
        }
    }

    public function namespaces()
    {
        return $this->model->distinct()->pluck('namespace')->filter()->toArray();
    }
}

4. 替换Laravel默认加载器

在AppServiceProvider的register方法中绑定自定义加载器:

// app/Providers/AppServiceProvider.php
use App\Translation\DatabaseTranslationLoader;
use App\Models\Translation;

public function register()
{
    $this->app->extend('translation.loader', function ($originalLoader, $app) {
        return new DatabaseTranslationLoader(new Translation());
    });
}

5. 动态管理与使用

  • 后台通过CRUD操作translations表实现翻译新增/修改
  • 使用Laravel原生翻译函数即可调用数据库中的翻译内容

最佳实践注意事项

  1. 语言回退配置
    在config/app.php中设置 fallback 语言,避免翻译缺失:
'fallback_locale' => 'en',
  1. 支持的语言列表
    添加可用语言配置,用于验证动态切换的语言:
'available_locales' => ['en', 'zh-CN', 'fr', 'de'],
  1. 动态切换语言中间件
    编写中间件根据URL参数、Cookie或请求头切换语言:
// app/Http/Middleware/SetLocale.php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\App;

class SetLocale
{
    public function handle($request, Closure $next)
    {
        $availableLocales = config('app.available_locales');
        // 优先取URL参数
        if ($request->has('locale') && in_array($request->locale, $availableLocales)) {
            App::setLocale($request->locale);
            cookie()->queue('locale', $request->locale, 365 * 24 * 60);
        } 
        // 其次取Cookie
        elseif ($request->cookie('locale') && in_array($request->cookie('locale'), $availableLocales)) {
            App::setLocale($request->cookie('locale'));
        }
        return $next($request);
    }
}

将中间件注册到web中间件组即可生效。


内容的提问来源于stack exchange,提问作者PHP LARAVEL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 20:34:55