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

Laravel中如何将Locale参数从Job传递到Controller?

在Laravel Job中发起Http请求时传递Locale并让Controller生效的解决方案

问题背景

需要在Laravel Job的handle方法内发起Http Post请求时,传递指定Locale参数并让其在对应Controller中生效,要求使用App::setLocale相关逻辑而非URL参数传递。当前使用astrotomic/laravel-translatable扩展,默认Locale为en,但Job中设置的Locale无法在Controller中生效。

相关配置与代码

config/translatable.php 配置

'locales' => [
    'en',
    'fr',
    // ...其他语言
],

'locale' => null,
// ...其他配置

BannersCRUDTest Job 代码

<?php

namespace App\Jobs;

class BannersCRUDTest implements ShouldQueue
{
    public function handle()
    {
        $currentLocale = 'fr'; // 指定法语

        App::setLocale($currentLocale);
        session()->put('locale', $currentLocale); // 此方式无效

        $response = Http::post(route('banners.filter'));
    }
}

BannerController 代码

class BannerController extends Controller
{
    public function filter(): array
    {
        \Log::info(' -1 BannerController app()->getLocale()::'); // 日志显示为'en'
        \Log::info(app()->getLocale());
        // ...其他逻辑
    }
}

依赖版本

"laravel/framework": "^9.19",
"guzzlehttp/guzzle": "^7.2",
"astrotomic/laravel-translatable": "^11.11",
"mxl/laravel-job": "^1.3",

解决方案

核心原因:Job队列进程与Http请求进程完全独立,Job内的Locale设置无法直接传递给新发起的Http请求,需通过请求头传递Locale并在服务端中间件中处理

步骤1:在Job的Http请求中添加自定义Locale请求头

修改Job的handle方法,通过withHeaders传递Locale:

public function handle()
{
    $currentLocale = 'fr';

    $response = Http::withHeaders([
        'X-Locale' => $currentLocale, // 自定义请求头传递Locale
    ])->post(route('banners.filter'));
}

步骤2:创建中间件处理Locale请求头

生成中间件:

php artisan make:middleware SetLocaleFromHeader

编辑中间件代码,验证并设置Locale:

<?php

namespace App\Http\Middleware;

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

class SetLocaleFromHeader
{
    public function handle(Request $request, Closure $next)
    {
        // 从请求头获取Locale并验证是否在允许列表中
        if ($locale = $request->header('X-Locale')) {
            if (in_array($locale, config('translatable.locales'))) {
                App::setLocale($locale);
            }
        }

        return $next($request);
    }
}

步骤3:注册中间件

将中间件注册到对应路由或中间件组:

  • 方式1:添加到api或web中间件组(在app/Http/Kernel.php中):
protected $middlewareGroups = [
    'api' => [
        // ...其他中间件
        \App\Http\Middleware\SetLocaleFromHeader::class,
    ],
];
  • 方式2:单独绑定到目标路由:
Route::post('/banners/filter', [BannerController::class, 'filter'])
    ->name('banners.filter')
    ->middleware(\App\Http\Middleware\SetLocaleFromHeader::class);

效果验证

此时Controller中调用app()->getLocale()将返回请求头中传递的fr,满足需求且无需修改URL参数。


内容的提问来源于stack exchange,提问作者Petro Gromovo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 14:50:32