Laravel обрабатывает необязательный параметр url как обязательный - PullRequest
2 голосов
/ 19 апреля 2020

Я пытаюсь сделать несколько URL-адресов иметь дополнительный префикс. Теперь я добавил только 2 URL в эту группу: базовый URL '/' и тестовый URL. Для базового URL все работает нормально. Но когда я пытаюсь достичь тестового URL без префикса, я получаю 404. В чем может быть проблема?

Вот часть моих маршрутов / сети. php

Route::group([
    'prefix' => '{lang?}',
    'where' => ['lang' => '[a-z]{2}'],
    'middleware' => 'localization'
], function () {
    Route::get('/', function () {
        return view('welcome');
    });

    Route::get('/test/me/please', function () {
        return 'Bla Bla Bla';
    });
});

И вот это вывод php artisan route:list:

+--------+----------+------------------------+------+---------+------------------+
| Domain | Method   | URI                    | Name | Action  | Middleware       |
+--------+----------+------------------------+------+---------+------------------+
|        | GET|HEAD | api/user               |      | Closure | api,auth:api     |
|        | GET|HEAD | {lang?}                |      | Closure | web,localization |
|        | GET|HEAD | {lang?}/test/me/please |      | Closure | web,localization |
+--------+----------+------------------------+------+---------+------------------+

Ответы [ 2 ]

0 голосов
/ 20 апреля 2020

Laravel просто не нравятся дополнительные префиксы, когда после него есть дополнительный путь, так как он путается при сопоставлении (как доказано в вашем коде, где '/' работает, но другой путь не работает), поэтому вам следует избегать его в вашем случае, однако, есть другой способ реализовать то, что вы хотите сделать, и это путем указания двух маршрутов, где один имеет обязательный параметр lang, а другой нет.

Хотя это не будет выглядеть красиво так как он удваивает ваши маршруты, вот как я бы его структурировал:

// Prepare your routes as a closure
$myRoutes = function(){
    Route::get('/', function () {
        return view('welcome');
    });

    Route::get('/test/me/please', function () {
        return 'Bla Bla Bla';
    });
};


// Create a group that will use the middleware if it has the prefix
Route::group([
      'prefix' => '{lang}',
      'where' => ['lang' => '[a-z]{2}'],
      'middleware' => 'localization'
  ], $myRoutes
);

// Redefine the routes to handle when there is no lang prefix
$myRoutes();

Это может не сработать для вас, в зависимости от того, как структурированы другие ваши маршруты

0 голосов
/ 20 апреля 2020

Вот один из способов go об этом:

function getSubDomain()
    {
        $host = parse_url(url()->current())['host'];
        $exploded = explode('.', $host);

        array_pop($exploded); //remove TLD
        array_pop($exploded); //remove domain
        return $exploded[0] ?? null; //returns null if no subdomain is passed
    }

Создайте промежуточное ПО и примените его к вашей группе маршрутов. В промежуточном программном обеспечении вызовите указанную выше функцию, чтобы получить префикс / поддомен и добавить к объекту запроса, например:

public function handle($request, Closure $next)
    {
        $subdomain = $this->getSubdomain();
        $request->merge(['subdomain' => $subdomain]);

        return $next($request);
    }

. Таким образом вы можете объявить свой маршрут следующим образом:

Route::group([
    'middleware' => 'sub.parse' // need to be declared in app/Http/Kernel.php
], function () {
    Route::get('/', function () {
        $subdomain = request('subdomain'); // suddomain already available in request object
    });

    Route::get('/test/me/please', function () {
        return 'Bla Bla Bla';
    });
});

Поэтому, где бы вам ни понадобился поддомен, вы можете получить его из объекта запроса, например $request->subdomain

...