【问题标题】:Laravel route redirecting with dataLaravel 路由数据重定向
【发布时间】:2020-03-24 01:14:03
【问题描述】:

我的基本路线如下所示:

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。在这种情况下,我希望它重定向到 id,值为 1

我尝试使用Route:redirect,但无法正常工作。它看起来像这样:

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

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

发生的情况是,如果我声明了路由重定向,则会收到 404 错误。

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

【问题讨论】:

  • 您可以使用Regular Expression Constraints 只允许数值
  • @kerbholz 这确实是个好主意,但在我的情况下它不起作用,因为为了缓存路由,不能有闭包。
  • 在 where 子句中使用正则表达式的三元?
  • 您可以在 routes/web.py 中创建一个捕获非数字 id 的路由并将其重定向到 id=1 的“view-user”
  • @ege 这正是我想要做的,但我不知道怎么做。如果您能提供代码示例,将不胜感激。

标签: php laravel routing


【解决方案1】:

跟进评论

您可以在 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]);
}

您可以在this SO thread 中看到更多关于重定向和缓存的信息。

【讨论】:

  • 是的,但遗憾的是,由于缓存,我不能在此使用闭包
  • 所以将其添加为Controller的方法? IE。 '控制器@redirectBadInput'
  • 看到这个关于重定向缓存的信息:stackoverflow.com/questions/35613579/…
  • 也许这是唯一的办法
【解决方案2】:

你声明它是倒置的。

在 Laravel 中,您可以通过这种方式重定向传递的参数:

您可以传递名称而不是 url,并且只需传递变量。

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

【讨论】:

  • 我不是在问如何进行重定向,而是如何在web.php 文件中声明重定向规则。我希望整个逻辑都在 routes/web.php file 中,而不是在控制器中。
【解决方案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。

【讨论】:

  • 我再次更新了这个问题。我之前在下面的评论中说过,关闭不是我的选择。我现在把它放在问题中。
【解决方案4】:

在路由中指定路由名称。

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 中,而不是在控制器中,而且闭包对我来说不是一个选项
  • 正如我所说,这里不能选择关闭
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-07
  • 2017-06-19
  • 2022-01-26
  • 2021-04-26
  • 1970-01-01
  • 1970-01-01
  • 2017-04-17
相关资源
最近更新 更多