Laravel路由重定向并携带数据

5
我有一个基本路由,看起来像这样:

Route::prefix('/group')->group(function () {
    // Some routes here
    Route::prefix('/{uuid}')->group(function () {
        // Some routes here
        Route::get('/user/{id}', 'Controller@preview')->name('view-user')->where('id', '[0-9]+');
    }
}

逻辑是我希望id只能是数字值。现在我想做的是,如果值是非数字,则声明重定向到此值。假设id的输入是fs。在这种情况下,我想将其重定向到具有值1id
我尝试使用Route:redirect,但无法使其工作。它看起来像这样:
Route::redirect('/group/{uuid}/user/{id}', '/group/{uuid}/user/1')->where('id', '[^0-9]+');

我更倾向于将重定向放在组内,但如果这是唯一的方法,它也可以放在组外。任何帮助都将不胜感激。

问题是,如果我声明了路由重定向,就会出现404错误。

编辑: 我想在routes/web.php文件中执行此操作。我知道如何在控制器中执行此操作,但在当前情况下这不是我所需要的。闭包也不是一个选择,因为会防止路由缓存。


1
您可以使用正则表达式约束来仅允许数字值。 - brombeer
在where子句中使用带有正则表达式的三元运算符,可以吗? - user3532758
@user3532758 你具体有什么想法? - Martin Dimitrov
1
你可以在routes/web.py中创建一个路由,捕获非数字id并将其重定向到'id=1'的'view-user'页面。 - ege
2
@ege 这正是我想要做的,但我不知道如何操作。如果您能提供一份代码示例,将不胜感激。 - Martin Dimitrov
显示剩余3条评论
4个回答

3

你将它声明为倒置。

Laravel中,你可以通过以下方式传递参数进行重定向:

你可以传递名称而不是URL,并且简单地传递变量。

Redirect::route('view-user', [$uuid, $id])


我不是在问如何进行重定向,而是如何在web.php文件中声明重定向规则。我希望整个逻辑都在routes/web.php文件中,而不是在控制器中。 - Martin Dimitrov

3

我认为您可以在路由控制器内部完成此操作,使用以下逻辑:

class Controller {
    // previous code ..

    public function preview($uuid, $id) {
        if(! is_numeric($id))
            return redirect("/my-url/1");

        // run the code below if $id is a numeric value..
        // if not, return to some url with the id = 1
    }
}

我认为在laravel中没有覆盖'where'函数的方法,但我猜可能在Routing Bindings中有类似的功能:
或者,您可以重写您的Eloquent模型上的resolveRouteBinding方法。该方法将接收URI段的值,并应返回应注入路由的类的实例:
/**
 * Retrieve the model for a bound value.
 *
 * @param  mixed  $value
 * @return \Illuminate\Database\Eloquent\Model|null
 */
public function resolveRouteBinding($value)
{
    return $this->where('name', $value)->first() ?? abort(404);
}

但是需要管理简明模型值,而不是任何你想要的id。


我已经再次更新了问题。之前在下面的评论中已经声明了,闭包对我来说不是一个选项。现在我已经把它放在问题中了。 - Martin Dimitrov

3

跟进评论:

你可以在路由文件routes / web.php中创建一个路由,捕获非数字ID,并将其重定向到'id = 1'的'view-user'

这看起来会像这样:

Route::get('/group/{uuid}/user/{id}', function ($uuid, $id) {
  return redirect('view-user', ['uuid' => $uuid, 'id' => 1]);
})->where('id', '[^0-9]+');

// and then below have your normal route

Route::get('/group/{uuid}/user/{id}', 'Controller@preview')->name('view-user')->where('id', '[0-9]+');

更新

根据您的评论,您不想使用闭包。

将“错误输入路由”更改为:

Route::get('/group/{uuid}/user/{id}', 'Controller@redirectBadInput')->where('id', '[^0-9]+');

然后在Controller类中添加该方法:

public function redirectBadInput ($uuid, $id) {
  return redirect('view-user', ['uuid' => $uuid, 'id' => 1]);
}

关于重定向和缓存的更多信息,请查看此SO线程


是的,但不幸的是,由于缓存的原因,我不能在这里使用闭包。 - Martin Dimitrov
将其添加为“Controller”的方法?即“Controller@redirectBadInput”。 - ege
请参考以下关于重定向缓存的内容:https://dev59.com/KJTfa4cB1Zd3GeqPQnCb - ege
也许这真的是唯一的解决方法。 - Martin Dimitrov

1
在路由中指定路由名称,就像这样。
return Redirect::route('view-user', ['uuid'=>$uuid,'id'=>$id]);

那么你想要在web.php文件中。

Route::get('/group/{uuid}/user/{id}', function($uuid, $id){
    echo $uuid;
    echo $id;
})->name('view-user')->where('id', '[0-9]+');

正如我之前所述,我必须将其放在 routes/web.php 中,而不是控制器中,闭包对我也不是一个选项。 - Martin Dimitrov
正如我所说,闭包在这里不是一个选项。 - Martin Dimitrov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接