Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regular expression route constraint for a resource route

Laravel offers the possibility to add regular expression constraint to a route like this:

Route::get('user/{name}', function($name)
{
    //
})
->where('name', '[A-Za-z]+');

it is also possible to create multiple routes for a resource:

Route::resource('photo', 'PhotoController');

I want to add regular expression constraint only to the route GET /photo/{id}

is that possible?

like image 359
Mohamed Bouallegue Avatar asked Mar 24 '14 23:03

Mohamed Bouallegue


People also ask

Can we add constraints to the route if yes explain how we can do it?

Creating Route Constraint to a Set of Specific Values MapRoute( "Default", // Route name "{controller}/{action}/{id}", // Route Pattern new { controller = "Home", action = "Index", id = UrlParameter. Optional }, // Default values for parameters new { controller = "^H.

What is Route constraint?

You use route constraints to restrict the browser requests that match a particular route. You can use a regular expression to specify a route constraint. For example, imagine that you have defined the route in Listing 1 in your Global. asax file.

What does route :: resource do?

Route::resource: The Route::resource method is a RESTful Controller that generates all the basic routes required for an application and can be easily handled using the controller class.

What is resource routing in laravel?

Because of this common use case, Laravel resource routing assigns the typical create, read, update, and delete ("CRUD") routes to a controller with a single line of code.


3 Answers

In Laravel 5 resourceful route parameters can be named like this:

Route::resource('user', 'UserController', ['parameters' => [
   'user' => 'id'
]]);

This can be combined with route patterns:

Route::pattern('id', '[0-9]+');

So you can easily define a single global constraint for route parameters and use if for all of your resourceful routes.

like image 197
Mouagip Avatar answered Oct 21 '22 22:10

Mouagip


In your RouteServiceProvider boot() method, just reference the parameter name using Route::pattern('parameter', 'regex'). Note: the parameter name is the singular (if path is plural) of the path.

public function boot()
{
    Route::pattern('photo', '[0-9]+');

    parent::boot();
}

This would work for both:

Route::resource('photo', 'PhotoController');

and

Route::resource('photos', 'PhotoController');

Note: if you typehint your parameter to the model, this is not necessary. For example:

public function show(Photo $photo)
{
    //
}

Now, if a non-matching parameter is passed, a 404 | Not Found will be returned. But if you are using Route::fallback() to handle unmatched routes, you should keep Route::pattern('parameter', 'regex').

like image 38
PhillipMcCubbin Avatar answered Oct 22 '22 00:10

PhillipMcCubbin


As far as I know you can't but you may mimic that using something like this (route filtering):

public function __construct()
{
    $this->beforeFilter('checkParam', array('only' => array('getEdit', 'postUpdate')));
}

This is an example of route filtering using the constructor and here I've filtering only two methods (you may use except or nothing at all) and declared the filter in filters.php file as given below:

Route::filter('checkParam', function($route, $request){
    // one is the default name for the first parameter
    $param1 = $route->parameter('one');
    if(!preg_match('/\d/', $param1)) {
        App::abort(404);
        // Or this one
        throw new Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
    }
});

Here, I'm checking the first parameter manually (parameters method returns an array of all parameters passed to the route) and if it's not a digit then throwing NotFoundHttpException exception.

You may also catch the exception by registering a handler like this:

App::missing(function($exception){
    // show a user friendly message or whatever...
});
like image 39
The Alpha Avatar answered Oct 22 '22 00:10

The Alpha