行业资讯 laravel 怎么优雅的实现api的多语言?

laravel 怎么优雅的实现api的多语言?

40
 

在 Laravel 中实现 API 的多语言支持,可以通过以下步骤优雅地实现:

一、基础配置

  1. 安装语言包

   composer require overtrue/laravel-lang

这会提供 127 种语言的翻译文件。

  1. 发布语言文件

   php artisan lang:publish --all

生成 resources/lang 目录下的多语言文件模板。

  1. 设置默认语言config/app.php 中配置:

   'locale' => 'en', // 默认语言
   'fallback_locale' => 'en', // 备选语言

二、动态语言检测机制

1. 通过请求头识别

在 API 中间件中解析 Accept-Language 头:

// app/Http/Middleware/LanguageMiddleware.php
public function handle($request, $next)
{
    $locale = $request->header('Accept-Language', config('app.locale'));
    app()->setLocale($locale);
    return $next($request);
}

2. 路由参数显式指定

定义路由时允许通过 URL 指定语言:

// routes/api.php
Route::prefix('{locale}')->group(function () {
    Route::get('users', [UserController::class, 'index']);
});

三、翻译文件管理

  1. 模块化拆分resources/lang/en 下的文件按功能拆分:

   resources/
     └── lang/
         └── en/
             ├── auth.php       # 认证相关翻译
             ├── products.php   # 产品相关翻译
             └── validation.php # 验证消息翻译
  1. 使用 JSON 格式(推荐)对 API 响应,使用 JSON 翻译文件支持动态键名:

   // resources/lang/en/products.json
   {
     "product_not_found": "Product :name not found.",
     "price": "Price: :amount"
   }

四、响应层集成

1. 在 API 资源中使用翻译

// app/Http/Resources/UserResource.php
public function toArray($request)
{
    return [
        'id' => $this->id,
        'name' => __('users.name', ['name' => $this->name]),
        'email' => $this->email,
    ];
}

2. 错误消息本地化

自定义异常处理器:

// app/Exceptions/Handler.php
public function register()
{
    $this->renderable(function (ValidationException $e) {
        return response()->json([
            'errors' => $e->errors()->getMessages(),
            'message' => __('validation.error_header')
        ], 422);
    });
}

五、高级场景处理

1. 数据库内容翻译

使用 spatie/laravel-translatable 包:

composer require spatie/laravel-translatable

在模型中定义翻译字段:

// app/Models/Product.php
use Spatie\Translatable\HasTranslations;

class Product extends Model
{
    use HasTranslations;

    public $translatable = ['name', 'description'];
}

2. 日期/数字格式化

使用 Laravel 的本地化工具:

// 日期格式化
$date = now()->locale(app()->getLocale())->formatLocalized('%Y年%m月%d日');

// 数字格式化
$price = number_format(1234.56, 2, '.', ' '); // 根据语言环境自动适配

六、性能优化

  1. 缓存翻译文件

   use Illuminate\Support\Facades\Cache;

   $translated = Cache::remember("users.{$this->id}", 60, function () {
       return __('users.name', ['name' => $this->name]);
   });
  1. 自动化测试使用 Artisan 命令检测缺失翻译:

   php artisan lang:missing en

七、完整示例流程

  1. 请求进入

   GET /api/zh-CN/users
   Accept-Language: zh-CN,zh;q=0.9
  1. 中间件处理

  • 解析到 zh-CN,设置 App::setLocale('zh-CN')

  1. 控制器响应

   return UserResource::collection(User::all());
  1. 资源类输出

   [
     {
       "id": 1,
       "name": "张三", // 从 zh-CN/users.json 获取翻译
       "email": "zhangsan@example.com"
     }
   ]

通过以上步骤,你可以实现:

  • 无缝多语言切换:通过请求头或 URL 参数动态切换

  • 代码可维护性:翻译文件模块化,避免臃肿

  • 高性能:缓存和延迟加载优化

  • 扩展性:支持数据库内容翻译和复杂格式化需求


更新:2025-04-09 11:24:27 © 著作权归作者所有
QQ
微信
客服