Laravel路由本地化:/blog对应en,/uk/blog对应uk的实现方法
Laravel路由本地化:限制Locale仅匹配指定值并设置默认值
你的问题出在没有对{locale?}参数做匹配约束,导致Laravel会把blog当作locale参数解析。可以通过以下两种方式解决:
方法一:给路由参数添加约束并设置默认值
直接在路由组中对locale参数添加正则匹配规则,限制其只能为uk,同时设置默认值为en:
Route::group([ 'prefix' => '{locale?}', 'where' => ['locale' => 'uk'], // 仅允许匹配"uk" 'middleware' => 'setlocale' // 后续需创建该中间件处理locale设置 ], function() { Route::get('blog', 'App\Http\Controllers\BlogController@index'); // 更多路由 })->defaults('locale', 'en'); // 设置默认locale为en
配套中间件实现
创建SetLocale中间件来应用locale设置:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Support\Facades\App; class SetLocale { public function handle($request, Closure $next) { // 从路由参数获取locale,默认值为en $locale = $request->route('locale') ?? 'en'; App::setLocale($locale); return $next($request); } }
记得在app/Http/Kernel.php中注册这个中间件:
protected $routeMiddleware = [ // 其他中间件 'setlocale' => \App\Http\Middleware\SetLocale::class, ];
方法二:拆分路由组(更直观)
如果觉得参数约束的写法不够直观,可以拆分出默认路由组和指定locale的路由组:
// 默认英文路由(locale=en) Route::group(['middleware' => 'setlocale'], function() { Route::get('blog', 'App\Http\Controllers\BlogController@index'); // 更多路由 }); // 乌克兰语路由(locale=uk) Route::group(['prefix' => 'uk', 'middleware' => 'setlocale'], function() { Route::get('blog', 'App\Http\Controllers\BlogController@index'); // 更多路由 });
对应的SetLocale中间件需要调整为:
public function handle($request, Closure $next) { $locale = $request->route()->getPrefix() === 'uk' ? 'uk' : 'en'; App::setLocale($locale); return $next($request); }
两种方法都能实现需求:访问/blog时locale设为en,访问/uk/blog时locale设为uk,且不会把blog误识别为locale参数。
内容的提问来源于stack exchange,提问作者NeverLock
相关产品推荐
相关产品推荐

