Laravel切换语言时同步动态修改URL对应语种路径的实现方法
实现方案
步骤1:配置多语言路由映射
首先在语言包目录下创建路由翻译文件,存储不同语言下的路径对应关系:lang/en/routes.php
<?php return [ 'articles' => 'articles', 'article_detail' => 'articles/{id}', // 其他路径的英文映射 ];
lang/ar/routes.php
<?php return [ 'articles' => 'مقالات', 'article_detail' => 'مقالات/{id}', // 其他路径的阿拉伯语映射 ];
步骤2:注册路由时使用翻译路径
定义路由时直接调用翻译函数生成对应语言的路径,同时给每个路由设置唯一名称:
// 示例路由定义 Route::get(__('routes.articles'), [ArticleController::class, 'index'])->name('articles.index'); Route::get(__('routes.article_detail'), [ArticleController::class, 'show'])->name('articles.show');
步骤3:新增全局 locale 中间件
创建中间件保证每次请求都能读取session中存储的语言设置,同步应用语言配置:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; class SetLocale { public function handle(Request $request, Closure $next) { if (session()->has('locale')) { app()->setLocale(session()->get('locale')); } return $next($request); } }
将中间件注册到app/Http/Kernel.php的web中间件组中:
protected $middlewareGroups = [ 'web' => [ // 其他原有中间件 \App\Http\Middleware\SetLocale::class, ], ];
步骤4:修改语言切换路由逻辑
原有直接返回上一页的逻辑无法适配路径翻译,需要解析上一页对应的路由,用新语言重新生成URL:
Route::get('/language/{locale}', function ($locale) { // 校验语言合法性,防止恶意输入 if (!in_array($locale, ['en', 'ar'])) { abort(400); } session()->put('locale', $locale); app()->setLocale($locale); // 解析上一页的路由信息 $previousRequest = app('request')->create(url()->previous()); try { $previousRoute = app('router')->getRoutes()->match($previousRequest); $routeName = $previousRoute->getName(); $routeParams = $previousRoute->parameters(); } catch (\Exception $e) { // 解析失败直接跳首页 return redirect('/'); } // 路由存在名称则生成对应语言的新URL,否则跳首页 if ($routeName) { return redirect()->route($routeName, $routeParams); } return redirect('/'); });
步骤5:(可选优化)前端直接生成目标语言URL
如果不想走中转跳转逻辑,也可以直接在视图层生成对应语言的完整URL,修改切换按钮代码如下:
<li class="nav-item lang-nav fw-bold ms-1 me-md-5"> @php $currentRouteName = \Route::currentRouteName(); $currentRouteParams = \Route::current()->parameters(); @endphp @if ($current_locale == $arabic_locale) <a class="nav-link text-mine-blue text-center" href="{{ route($currentRouteName, array_merge($currentRouteParams, ['locale' => $english_locale])) }}"> English </a> @endif @if ($current_locale == $english_locale) <a class="nav-link text-mine-blue text-center" href="{{ route($currentRouteName, array_merge($currentRouteParams, ['locale' => $arabic_locale])) }}"> عربي </a> @endif </li>
注意事项
- 所有需要支持多语言路径切换的路由都必须设置唯一的路由名
- 两种语言的路由翻译文件的key要完全对应,避免生成路由时找不到匹配项
- 如果路由存在动态参数(比如文章ID、分类slug等),上述逻辑会自动携带参数,不需要额外处理
内容的提问来源于stack exchange,提问作者Osama Amr
相关产品推荐
相关产品推荐

