简体   繁体   中英

Laravel route redirecting with data

I have a basic route that looks like this:

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]+');
    }
}

The logic is that I want the id to be only numerical value. What I want to do now is, to declare a redirection to this, if the value is non-numerical. Let's say the input of id is fs . In that case I would want it to redirect to id with value 1 .

I tried using Route:redirect , but could not make it work. It looks something like this:

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

I would prefer to put the redirect inside the groups, but it can be outside if this is the only way. Any help will be greatly appreciated.

What happens is, that I get a 404 error if I have the route redirect declared.

EDIT : I want to do it in the routes/web.php file. I know how to do it in the controller, but it is not what I need in the current case. Closures are not an option either, because that would prevent routes caching.

You declared it inverted.

In Laravel you can redirect passing parameters in this way:

You can pass the name instead of the url and simply pass variables.

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

I think that you can do it inside of the controller of the router, with a logic like this:

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
    }
}

I think that there is no way to override the 'where' function of laravel, but I guess that have something like that in Routing Bindings:

Alternatively, you may override the resolveRouteBinding method on your Eloquent model. This method will receive the value of the URI segment and should return the instance of the class that should be injected into the route:

/**
 * 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);
}

But it's require that you manage consise model's values instead of ids of whatever you want.

Following up on the comment

You can create a Route in routes/web.php file that catches non-digit ids and redirect this to 'view-user' with id=1

It would look something like this

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]+');

Update

Following you comment that you do not want to use closures.

Change the "bad input route" to

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

and then add the method in class Controller :

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

You can see more in this SO thread about redirects and caching.

assign route name in route as like.

return Redirect::route('view-user', ['uuid'=>$uuid,'id'=>$id]);

As you want in web.php file then.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM