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

ArminLinder's avatar

L5.4 Bug(?): passing optional parameters to controllers doesn't work

Can anyone please verify this finding, which I consider a bug in Laravel 5.4: in my web.php file I have a route ...

Route::get('test/{parentId?}/{name?}','myController@test');

The controller looks like so:

class myController extends Controller
{
//

public function test($parentId = 'default parentid',$name = "default name") {

    return "parentid: [$parentId] name: [$name]";
}

The webserver (artisan serve) is running on localhost:11111 and this is what I get if I test the route parameters:

localhost:111111/test:          parentid: [default parentid] name: [default name]
localhost:111111/test/pid:      parentid: [pid] name: [default name]
localhost:111111/test/pid/nme:  parentid: [pid] name: [nme]
localhost:111111/test/pid/: parentid: [pid] name: [default name]
localhost:111111/test//nme: (404) NotFoundHttpException (RouteCollection.php)

According to the debugger web.php is called, and the REQUEST_URL property does correctly read: /test//nme. Seems like the default parameter mechanism fails, if I omit the 1st parameter, but provide the second.

Is this a known issue, any workaround?

Armin.

0 likes
13 replies
Snapey's avatar

optional parameters does not mean you can just bang two slashes next to each other and consider that an omitted parameter.

I think you are being unrealistic expecting that to work.

4 likes
ArminLinder's avatar

Unrealistic expectation? Huh?

What does "optional parameters" mean then, if it doesn't mean that I can omit them? Any of them? Because one I cannot omit is not an "optional" parameter any more?

And how do you express an omitted parameter in an URL, if not by //, and why would it be "unrealistic" to expect this to work? Because // is evil for some reason?

If so, why does

http://localhost:11111/test//

correctly return

parentid: [default parentid] name: [default name]

To me, it doesn't look like a "unrealistic expectation", but anyway, if Laravel cannot support multiple optional parameters ... I can redefine the URL interface to work without.

Armin.

jlrdw's avatar

I guess OP isn't even willing to review my reply.

http://localhost:11111/test//

only works because it's at end. And me I'll stick to using the good ol querystring.

Edit: Have you tried to pass just a null if there's nothing to pass?

jlrdw's avatar

Ok here another framework but very similar: Study this good

Route::any('dog/indexlist/{search?}/{avail?}', 'App\Controllers\Dogs@indexList');

and

public function search()
    {
        $dogsearch = Cln::fixUrl(Input::get('psch'));
        $aval = Cln::fixUrl(Input::get('aval'));
        return Redirect::to('dog/indexlist/' . $dogsearch . '/' . $aval);
    }

    public function indexList($dogsearch = '0', $aval = '0')
    {

        $dogsearch = ($dogsearch != '0') ? $dogsearch : '';
        $aval = ($aval != '0') ? $aval : '';
        if (isset($_POST['submit'])) {
            $dogsearch = (isset($_POST['psch']) != '') ? $_POST['psch'] : '';
            $aval = (isset($_POST['aval']) != '') ? $_POST['aval'] : '';
        }
        /////// more code

Querystring is so easier.

ArminLinder's avatar

@jlrdw ... I did review your post, but not comment it, because what exactly is in your reply (--> pointer to the docs I already know) worth commenting? I re-read it, there isn't any note telling that only one single parameter may be omitted ...

Pass a "null", well, not a solution in any way. The definition of an optional parameter is that it may be absent, and the default kicks in. That's exactly what I did, and the result is evil //. Anyway, besides, how would you pass "null" in an URL?

Regarding your snippet ... what am I supposed to see there? As far as I see (haven't tried it) the router call to indexList would fail, if you omit the {search?} parameter from the URL, just like my call failed.

Where is the progress then?

Armin.

1 like
jlrdw's avatar

See new reply above, I code for you. NO BUG, with parameters there is a little more work, not easy like querystring.

Why a blank if not 0,

well could be c%

so a blank with % means show all, see how easy.

ArminLinder's avatar

@jlrdw: many thanks for trying to help, I really appreciate that. I understand your approach to work around the issue by providing the missing parameter, but for that to work, I guess, you'd have to change the route from

'App\Controllers\Dogs@indexList'

to

'App\Controllers\Dogs@Search'

and fix the typo in the redirect to indexList.

I really don't mean to upset you, or nit-pick, just in case someone finds this thread in the future and tries to implement your fix there should be a fair chance it works like it was posted.

For me, I'll go with an entirely different approach. I changed the optional parentId parameter to mandatory, and changed the interface description document :-)

PartenId may not be blank any longer, if the parentid isn't known one shall send 0 (or any non-numeric value he likes).

Mission accomplished, many thanks to all who tried to help.

jlrdw's avatar

That's not laravel code, but a similar framework, and yes there is a search route also, it was just a quick example of filling missing parameters with 0.

Edit, I tested in laravel 5.4, no bug, works right.

This

http://localhost/laravel54/ptest/0/hello

with controller code

public function ptest($a = null, $b = null)
    {
        $mya = ($a == 0 || isNull($a) ? '' : $a);
        echo 'mya====' . $mya. '<br>';
        echo $b;
    }

Gives

mya====

hello

Which is correct.

But

http://localhost/laravel54/ptest//hello

of course gives error, naturally you need to throw in a 0 or null, not a //

http://localhost/laravel54/ptest/null/hello

also works great.

jlrdw's avatar

Anyone landing here, it's like @Snapey said

optional parameters does not mean you can just bang two slashes next to each other and consider that an omitted parameter.

You have to put something there, I like a 0 or null.

But querystring is so much easier and has nothing to do with seo.

Please or to participate in this conversation.