Laravel: не передается параметр в функцию замыкания группы маршрутов
Начинаю делать многоязычный сайт. Язык решил обрабатывать как префикс в маршрутизации. В моем случае \routes\web.php выглядит так:
$languages = [null, 'ua', 'ru', 'en'];
foreach($languages as $language)
{
Route::prefix($language)->group(function($language)
{
//dd($language);
App::setlocale($language);
Auth::routes();
Route::get('/', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
});
}
Но функция App::setlocale() поучает в качестве аргумента объект класса Illuminate\Routing\Router вместо строки. В этом можно убедится раскоментировав dd($language);
Ответы (1 шт):
Чтобы самостоятельно находить ответы на вопросы типа "почему функция App::setlocale() поучает в качестве аргумента объект класса Illuminate\Routing\Router вместо строки?", надо научиться не доверять своим ожиданиям насчёт работы кода, а проверять как на самом деле код работает.
Давайте попробуем. Почему колбэк group должен принять аргумент $language? Обещано ли такое в документации Laravel? Что на самом деле происходит внутри функции group? В документации фрэймворка сказано, что группа позволяет применить атрибуты (например префикс) к нескольким роутам. Если заглянуть в код (вам может понадобиться IDE, чтобы не страдать изучая код Laravel), то ваш колбэк называется $routes (список маршрутов) и вызывается в \Illuminate\Routing\Router так: $routes($this);. Итог: Laravel и не должен передавать в этот колбэк параметр language.
Тогда как же работать с префиксами? В документации нет подходящего примера для префикса, но есть для поддомена:
Route::domain('{account}.example.com')->group(function () {
Route::get('user/{id}', function ($account, $id) {
//
});
});
$account появился в обработчике роута из {account}. Вариант с префиксом мог бы быть таким:
Route::prefix('{language}')->group(function () {
Route::get('/', function ($language) {
//
});
});
Важно понимать, что параметры типа {language} извлекаются из запроса, а не из вашего массива. Если вы хотите ограничить возможные варианты маршрутов, то смотрите как это сделать в документации (например можно ограничить возможные значения параметра регуляркой).
Чтобы применить для всех маршрутов общий обработчик, в котором устанавливается локаль, вам понадобится middleware. Постарайтесь понять их концепцию.