Я работал над добавлением локализации в свой проект Laravel 11 и создал промежуточное программное обеспечение под названием SetLocale
, которое состоит из кодовой базы, аналогичной приведенной ниже:
public function handle(Request $request, Closure $next): Response
{
App::setLocale(session()->get('locale'));
return $next($request);
}
Я добавил его в свой файл bootstrap/app.php
вот так:
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__ . '/../routes/web.php',
commands: __DIR__ . '/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
$middleware->append(SetLocale::class);
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();
В моем LocalizationController я установил сеанс следующим образом:
public function setLocalization(string $locale): RedirectResponse
{
session()->put('locale', $locale);
App::setLocale($locale);
return back();
}
Мой маршрут в web.php
выглядит так:
Route::get('/locale/{locale}', [LocalizationController::class, 'setLocalization'])->name('locale.switch');
Вот что я попробовал:
back()->with('locale', $locale);
при возврате в функцию setLocalization()
в LocalizationController, но это не сработало.Единственный способ заставить его работать — это обернуть промежуточное программное обеспечение вокруг маршрута следующим образом:
Route::prefix('localization')->middleware([SetLocale::class])->group(function() {
Route::get('/locale/{locale}', [LocalizationController::class, 'setLocalization'])->name('locale.switch');
});
Является ли мое использование глобального промежуточного программного обеспечения неправильным или Laravel изменил способ обработки сеансов для глобального промежуточного программного обеспечения?
К вашему сведению: Laravel теперь переместил свое промежуточное программное обеспечение в другое место. Теперь это чистый файл, расположенный в файле bootstrap/app.php.
Спасибо за вашу помощь.
Мне кажется, вы приняли мой пост за чужой. Это мой первый раз, когда я пишу о переполнении стека.
Возможно, вы совершенно правы, в таком случае проигнорируйте мой комментарий. Кто-то написал точно такую же проблему
Глобальное промежуточное программное обеспечение запускается перед промежуточным программным обеспечением маршрута. Промежуточное программное обеспечение, запускающее сеанс, является промежуточным программным обеспечением маршрутизации; при запуске глобального промежуточного программного обеспечения сеанс отсутствует. Добавьте свое промежуточное программное обеспечение в качестве промежуточного программного обеспечения маршрута ко всей группе нужных вам маршрутов точно так же, как группа web
применяется ко всем веб-маршрутам, или добавьте это промежуточное программное обеспечение в группу web
.
Чтобы расширить ответ, предоставленный @lagbox, промежуточное программное обеспечение, которое обрабатывает сеанс, определяется как часть группы промежуточного программного обеспечения маршрута web
. Оно не определяется как глобальное промежуточное программное обеспечение. Как упоминалось в @lagbox, промежуточное программное обеспечение маршрута запускается после глобального промежуточного программного обеспечения.
Метод append()
, который вы использовали в обратном вызове withMiddleware()
, добавит предоставленное промежуточное программное обеспечение к глобальному промежуточному программному обеспечению. Это не то, что вам нужно, поскольку ваше новое добавленное глобальное промежуточное программное обеспечение будет запускаться раньше промежуточного программного обеспечения сеанса, определенного в группе промежуточного программного обеспечения маршрута web
.
Чтобы получить желаемый результат, вы можете использовать метод appendToGroup()
вместо метода append()
. Это добавит ваше промежуточное программное обеспечение в указанную группу промежуточного программного обеспечения вместо того, чтобы добавлять его в качестве глобального промежуточного программного обеспечения.
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__ . '/../routes/web.php',
commands: __DIR__ . '/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
// Use appendToGroup() to add the middleware to the 'web' group.
$middleware->appendToGroup('web', SetLocale::class);
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();
Да, это сработало! Таким образом, метод addToGroup() означает то же самое, что оборачивать все наши маршруты web.php нашим промежуточным программным обеспечением SetLocale(). Спасибо!
Вы также можете сделать следующее вместо addToGroup() на случай, если кто-нибудь еще увидит это в будущем: $middleware->web(append: [ SetLocale::class ]);
Вы разместили это вчера, теперь я вижу, что пост удален, не делайте этого, не удаляйте пост и сделайте репост, если он не получит ожидаемого внимания...