Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

phpmaven's avatar

Pass an array of url parameters to controller

I'm trying to figure out how to turn the parameters in the url I'm trying to match into an array and pass them to my controller.

I have the following routes defined:

Route::get('/{parameter1}-{parameter2}-{parameter3}-{parameter4}-{page}.html', 'ListingController@show4')->where('page','^[0-9]+');
Route::get('/{parameter1}-{parameter2}-{parameter3}-{page}.html', 'ListingController@show3')->where('page','^[0-9]+');
Route::get('/{parameter1}-{parameter2}-{page}.html', 'ListingController@show2')->where('page','^[0-9]+');
Route::get('/{parameter1}-{page}.html', 'ListingController@show1')->where('page','^[0-9]+');

The urls would look like:

text-1.html
text-text-1.html
text-text-text-1.html
text-text-text-text-1.html

The key is that the last parameter will always be a number.

I would like to pass all of the parameters to the Show method as one array so that I can have just one "Show" method in the controller handle all 4 of these scenarios. I looked at making the parameters optional, but I couldn't see how to do that and still match the urls properly. If I could pass one array to a single "show" method, then I could just iterate the array and handle further processing depending on which parameters had values.

Hopefully that makes sense. I just want to be able to have one method handle this in the controller.

Thanks

0 likes
11 replies
biishmar's avatar

@phpmaven Route

Route::get('/{parameter}.html', 'ListingController@show')

Controller

public function show( $parameter )
    {
        $param = explode( '-', $parameter);
        
        $paramLength = count($param);
        
        // According to length redirect to specific view with data
    }
phpmaven's avatar

Thanks, but that would match every single url coming in. What I'm looking for is something like this:

Route::get('/{parameter1}-{parameter2}-{parameter3}-{parameter4}-{page}.html', function () {
        $parameters = $parameter1."-".$parameter2."-".$parameter3."-".$parameter4;
    // call ListingController@Show and pass $parameters to it.
});

Then I could do something like you suggest in the controller.

I don't know if something like this is possible, but it would save having to have 4 different methods to handle these 4 scenarios in the controller. Not the end of the world, but it would make the controller a bit cleaner.

jlrdw's avatar

Have you studied the documentation on optional parameters and methods it would work like this

public function show( $parameter1 = null,  $parameter2 = null,  $parameter3 = null,  $parameter4 = null)

That's all there is to it.

phpmaven's avatar

Yes, I'm aware of using optional parameters, however that doesn't solve my problem.

I have the following 4 routes defined:

Route::get('/{parameter1}-{parameter2}-{parameter3}-{parameter4}-{page}.html', 'ListingController@show')->where('page','^[0-9]+');
Route::get('/{parameter1}-{parameter2}-{parameter3}-{page}.html', 'ListingController@show')->where('page','^[0-9]+');
Route::get('/{parameter1}-{parameter2}-{page}.html', 'ListingController@show')->where('page','^[0-9]+');
Route::get('/{parameter1}-{page}.html', 'ListingController@show')->where('page','^[0-9]+'

If I send those all to the same "Show" method:

public function show( $parameter1 = null,  $parameter2 = null,  $parameter3 = null,  $parameter4 = null, page)

I get a "Too few arguments to function App\Http\Controllers\ListingController::show()" on all Routes except the first one.

You have to pass a parameter whether null or not, so it seems that I will need to stick with using 4 different methods, which is fine.

jlrdw's avatar

You don't need four routes just one route with the optional parameters. In your method handle how many parameters was passed with some if statements.

phpmaven's avatar

I'm trying to match the following 4 url scenarios:

text-1.html
text-text-1.html
text-text-text-1.html
text-text-text-text-1.html

If I only have one route:

Route::get('/{parameter1}-{parameter2}-{parameter3}-{parameter4}-{page}.html', 'ListingController@show')->where('page','^[0-9]+');

Then it will only match the last url.

jlrdw's avatar

Then I don't see the problem just have your four separate routes and I guess make four different methods. Or stick to one method and use some if statements or use switch. You probably need a / instead of a -

phpmaven's avatar

It's not a problem. I was just curious. Thanks for your help.

lostdreamer_nl's avatar

You could make it easier with a catch all regex route instead of all separate routes:

Route::get('/{parameters}-{num}.html', function ($parameters, $page) {
    $parameters = explode("-", $parameters);
    dd($parameters, $page);
})->where('parameters', '.*')->where('page','^[0-9]+');

$parameters will now be an array with your parameter1, parameter2, parameter3 etc.

phpmaven's avatar

@lostdreamer_nl Thank you so much for pointing me in the right direction. This is what I ended up with and it works great.

Route::get('/{parameter}-{page}.html', function ($parameter, $page) {
   $controller = \App()->make('\App\Http\Controllers\ListingController');
   $parameterArray = array();
   array_push($parameterArray, $parameter);
   array_push($paraparameterArraymeters, $page);
   return $controller->callAction('Show', $parameterArray);
})->where('parameter', '.*')->where('page','^[0-9]+');

I had to do quite a bit of searching to figure out how to call the controller inside the function. That's the bit I couldn't figure out.

Please or to participate in this conversation.