Laravel Localization возится с параметром Route Resource

Sep 22 2020

Во второй попытке я реализовал многоязычную реализацию для сайта, над которым я работаю, используя элемент, Route::groupкоторый prefixesиспользуется {locale}в первом сегменте URL-адреса routeMiddleware Kernel. Он работает очень хорошо, кроме случаев получения маршрута Resourcesс помощью parameters.

Реализация имеет сбой в том, что по какой-то причине она превращает parameterв %2F{id}(что неверно) и не получает PublicGalleriesControllerзапрашиваемый мной ресурс . Я не понимаю, почему, потому что, когда я наводю курсор на сгенерированный якорь, hrefя вижу правильный формат URL. Но когда я нажимаю на него, выдается 404 Not Foundсообщение с испорченным URL-адресом.

web.php Это моя группа маршрутов, которая инкапсулирует все маршруты с функцией

Route::group([
    'prefix' => '{locale}',
    'middleware' => 'setlocale',
], function() {

   // all my routes are within this route group including:
   Route::resource('gallery', 'PublicGalleriesController');

   Auth::routes();

   Route::group(['middleware' => 'auth'], function() {

       ...

   });

});

App / Http / Middleware / Localisation.php Маршрутное промежуточное ПО, которое маршрутизируется черезKernel.php

public function handle($request, Closure $next)
    {
        \App::setLocale($request->segment(1)); return $next($request);
    }

PublicGalleriesController.php Извлекает пути к изображениям из модели и возвращает их клиентскому представлению

    public function show($id)
    {
        // Show gallery group images for given group id
        $pics = null; $path = null;
        $path = GalleryGroup::find($id);
        
        $pics = Gallery::select('imagefilename', 'group_id')->where('group_id', $id)->orderBy('id', 'asc')->get()->toArray();

        return view('gallery.show', compact('pics', 'path'));
    }

Когда я парить над фото ссылка галерея группы , которая видна на index.bladeэто показывает в браузере левом углу , как: localhost/en/gallery/41. В index.bladeотыскивает галерея группы первичные ключи и строит HTML ссылки якорь в цикле:<a href="{{ url(app()->getLocale(), 'gallery/' . $item['id']) }}">{{$item['descrp']}}</a>

Когда я нажимаю эту ссылку, она должна PublicGalleriesControllerзапустить showфункцию и получить все эти фотографии группы галереи, но вместо этого вернет 404 Not Foundс отображаемым URL-адресом в браузере localhost/en/gallery%2F41. %2FЯ считаю , что это Url закодированного косой черты.

php artisan route:listпоказывает showресурс следующим образом:

| Domain | Method    | URI                         | Name         | Action   
         | Middleware                              |
+--------+-----------------------------------------+--------------+-----------------------
|        | GET|HEAD  | {locale}/gallery/{gallery}  | gallery.show | App\Http\Controllers\PublicGalleriesController@show   
         | web,setlocale                           |

Может ли кто-нибудь помочь мне понять, почему URL-адрес становится таким беспорядочным?

Версия Laravel: 5.6.39

Ответы

2 lagbox Sep 22 2020 at 03:49

Подпись для urlпомощника:

function url($path = null, $parameters = [], $secure = null)

$parametersпредставляет собой массив параметров, а не путь, поэтому он кодирует то, /что вы используете, поскольку параметры являются сегментом URL-адреса, а не путем.

Вы можете настроить вызов, чтобы urlиметь более полный путь или использовать parametersмассив в качестве дополнительных сегментов, а не путей:

url(app()->getLocale() .'/gallery/'. $item['id']); // 1 argument url(app()->getLocale() .'/gallery', [$item['id']]); // 2 arguments
url(app()->getLocale(), ['gallery', $item['id']]);  // 2 arguments

Вы также можете использовать routeпомощник:

route('gallery.show', ['locale' => app()->getLocale(), 'gallery' => $item['id']]);

Если вы не хотите передавать localeвсе URL-адреса, которые вы хотите сгенерировать с помощью routeпомощника, вы можете настроить промежуточное программное обеспечение, чтобы установить значение по умолчанию для этого параметра:

public function handle($request, Closure $next)
{
    App::setLocale($locale = $request->route('locale'));

    URL::defaults(['locale' => $locale]); // set default return $next($request);
}

Теперь вам не нужно передавать этот параметр:

route('gallery.show', ['gallery' => ...]);

Если вы не хотите, чтобы localeпараметр передавался всем «действиям» вашего маршрута (методы и замыкания контроллера), это тоже можно сделать. Вы можете добавить такую ​​строку к этому промежуточному программному обеспечению, прежде чем возвращать ответ:

$request->route()->forgetParameter('locale');