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
相关产品推荐
相关产品推荐

