Laravel 将可选的 url 参数视为必需的

我试图让几个 url 有可选的前缀。现在我只向该组添加了 2 个 url:基本 url '/' 和测试 url。对于基本网址,一切正常。但是当我尝试访问不带前缀的测试 url 时,我得到 404。问题可能出在哪里?


这是我的 routes/web.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 |

+--------+----------+------------------------+------+---------+------------------+


德玛西亚99
浏览 142回答 3
3回答

阿晨1998

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 prefixRoute::group([      'prefix' => '{lang}',      'where' => ['lang' => '[a-z]{2}'],      'middleware' => 'localization'  ], $myRoutes);// Redefine the routes to handle when there is no lang prefix$myRoutes();这可能对您不起作用,具体取决于您其他路线的结构

婷婷同学_

这是一种解决方法: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

慕侠2389804

我在这里看到的唯一问题是中间件。我在本地测试过它'middleware' => 'web'并且工作正常。然后我切换到'middleware' => 'localization'它开始抛出错误。所以我创建了一个新的中间件并再次测试它,但它还没有工作。所以我在数组下注册了中间件,运行App\Http\Kernel,刷新页面,它又开始工作了。$routeMiddlewarephp artisan config:cache所以我想注册localization中间件应该可以解决问题。PS> 我使用的路线是:.../en/test/me/please. 另一个可能的问题可能是您输入了这样的内容:(.../enasdf/test/me/please超过 2 个字符的语言)或这个:(.../test/me/please/en末尾的可选参数)。在这些情况下,它会抛出 404 未找到。
打开App,查看更多内容
随时随地看视频慕课网APP