为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

PHP
德玛西亚99 2022-12-30 17:39:45
我试图让几个 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 |+--------+----------+------------------------+------+---------+------------------+
查看完整描述

3 回答

?
阿晨1998

TA贡献2037条经验 获得超6个赞

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();

这可能对您不起作用,具体取决于您其他路线的结构


查看完整回答
反对 回复 2022-12-30
?
婷婷同学_

TA贡献1844条经验 获得超8个赞

这是一种解决方法:


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


查看完整回答
反对 回复 2022-12-30
?
慕侠2389804

TA贡献1719条经验 获得超6个赞

我在这里看到的唯一问题是中间件。

我在本地测试过它'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 未找到。



查看完整回答
反对 回复 2022-12-30
  • 3 回答
  • 0 关注
  • 132 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号