Laravel (5) - Routing to controller with optional parameters

I'd like to create a route that takes a required ID, and optional start and end dates ('Ymd'). If dates are omitted, they fall back to a default. (Say last 30 days) and call a controller....lets say 'path@index'

Route::get('/path/{id}/{start?}/{end?}', function($id, $start=null, $end=null)
{
    if(!$start)
    {
        //set start
    }
    if(!$end)
    {
        //set end
    }

    // What is the syntax that goes here to call 'path@index' with $id, $start, and $end?
});

Any help would be appreciated. I'm sure there is a simple answer, but I couldn't find anything anywhere.

Thanks in advance for the help!


Solution 1:

There is no way to call a controller from a Route:::get closure.

Use:

Route::get('/path/{id}/{start?}/{end?}', 'Controller@index');

and handle the parameters in the controller function:

public function index($id, $start = null, $end = null)
{
    if (!$start) {
        // set start
    }
        
    if (!$end) {
        // set end
    }
        
    // do other stuff
}

Solution 2:

This helped me simplify the optional routes parameters (From Laravel Docs):

Occasionally you may need to specify a route parameter, but make the presence of that route parameter optional. You may do so by placing a ? mark after the parameter name. Make sure to give the route's corresponding variable a default value:

Route::get('user/{name?}', function ($name = null) {
    return $name;
});

Route::get('user/{name?}', function ($name = 'John') {
    return $name;
});

Or if you have a controller call action in your routes then you could do this:

web.php

Route::get('user/{name?}', 'UsersController@index')->name('user.index');


userscontroller.php

public function index($name = 'John') {

  // Do something here

}

I hope this helps someone simplify the optional parameters as it did me!

Laravel 5.6 Routing Parameters - Optional parameters

Solution 3:

I would handle it with three paths:

Route::get('/path/{id}/{start}/{end}, ...);

Route::get('/path/{id}/{start}, ...);

Route::get('/path/{id}, ...);

Note the order - you want the full path checked first.