Laravel (5) - Routing to controller with optional parameters

RoutingLaravel 5

Routing Problem Overview


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!

Routing Solutions


Solution 1 - Routing

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

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

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.

Solution 4 - Routing

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

Find more details here (Laravel 7) : https://laravel.com/docs/7.x/routing#parameters-optional-parameters

Solution 5 - Routing

You can call a controller action from a route closure like this:

Route::get('{slug}', function ($slug, Request $request) {

	$app = app();
	$locale = $app->getLocale();

    // search for an offer with the given slug
	$offer = \App\Offer::whereTranslation('slug', $slug, $locale)->first();
	if($offer) {
		$controller = $app->make(\App\Http\Controllers\OfferController::class);
		return $controller->callAction('show', [$offer, $campaign = NULL]);
	} else {
        // if no offer is found, search for a campaign with the given slug
		$campaign = \App\Campaign::whereTranslation('slug', $slug, $locale)->first();
		if($campaign) {
			$controller = $app->make(\App\Http\Controllers\CampaignController::class);
			return $controller->callAction('show', [$campaign]);
		}
	}

	throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

});

Solution 6 - Routing

What I did was set the optional parameters as query parameters like so:

Example URL: /getStuff/2019-08-27?type=0&color=red

Route: Route::get('/getStuff/{date}','Stuff\StuffController@getStuff');

Controller:

public function getStuff($date)
{
        // Optional parameters
        $type = Input::get("type");
        $color = Input::get("color");
}

Solution 7 - Routing

Solution to your problem without much changes

Route::get('/path/{id}/{start?}/{end?}', function($id, $start=null, $end=null)
{
    if(empty($start))
    {
        $start = Carbon::now()->subDays(30)->format('Y-m-d');
    }
    if(empty($end))
    {
        $end = Carbon::now()->subDays(30)->format('Y-m-d');
    }
    return App\Http\Controllers\HomeController::Path($id,$start,$end);
});

and then

class HomeController extends Controller
{
public static function Path($id, $start, $end)
    {
        return view('view');
    }
}

now the optimal approach is

use App\Http\Controllers\HomeController;
Route::get('/path/{id}/{start?}/{end?}', [HomeController::class, 'Path']);

then

class HomeController extends Controller
{
    public function Path(Request $request)
    {
        if(empty($start))
        {
            $start = Carbon::now()->subDays(30)->format('Y-m-d');
        }
        if(empty($end))
        {
            $end = Carbon::now()->subDays(30)->format('Y-m-d');
        }
        //your code
        
        return view('view');
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSteveView Question on Stackoverflow
Solution 1 - RoutingMichael PittinoView Answer on Stackoverflow
Solution 2 - RoutingOlaJView Answer on Stackoverflow
Solution 3 - RoutingLea de GrootView Answer on Stackoverflow
Solution 4 - RoutingHicham O-SfhView Answer on Stackoverflow
Solution 5 - RoutingAlexView Answer on Stackoverflow
Solution 6 - RoutingCuteduView Answer on Stackoverflow
Solution 7 - RoutingArpan MauryaView Answer on Stackoverflow