We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

phalcon converts zero to null when passed as last parameter in url

Dear phalconists/phalconistas

I need to pass IDs into a controller action, i do it like this (id = 101):

https://my.site.com/ctrl/action/101

Sometimes the ID is 0 (the number zero):

https://my.site.com/ctrl/action/0

In this case the "params" parameter is NULL, the 0 disappears from phalcon. It's still visible in the _REQUEST array, though. That is, it appears that in phalcon you cannot pass the value 0 via the url/route if it's the last value.

Is there a way around this?



2.1k

may i know why you use number 0?

try doing this..

if param === 0 param === null

edited Jan '15

Hi 7thcubic

I don't "use" the value 0. It's an ID, some items may have ID=0. I will not necesarily be able to control that.

/mycontroler/edit/-1

Will lead to editing item with ID=-1.

/mycontroler/edit/1

Will lead to editing item with ID=1. But

/mycontroler/edit/0

Wil lead to params being null.

Still, looking at the output of route->getMatches() shows that the value is still there, so phalcon has no troble picking up the 0. It just decides to through it away later. This makes no sense to me. 0 is a perfectly valid value, I don't see why 0 should be treated so radically different from any other number.

The further point is that what I'm building could reasonably see the value 0 as a parameter in lots of situations. It would feel totally absurd to either tell all clients never to use 0 or to have to code around such an issue.

I seriously hope it's either a bug or a conscious decided feature that can be disabled.

As for your suggestion to convert nulls to the value 0, that would be equivalent to decide that every time there is a no value the user probably meant "0" (whatever 0 meight reperesent in that specific situation), imagine all the checks to figure out whether it really was a request for choice 0 or one of an essentally endless list of unknown situations.



2.1k
edited Jan '15

you will be able to control it bro.

ID is normally auto increment in database.

and it will never be 0

also its a php thing. infact its a programming language thing.

in boolean, 0 = false, 1 = true in null or not, 0 = null, 1 = not null

because of how it the language was made each variable is made so it can be anything in php.

thus when you want to find out its value in comparision, it cant determine if its a NULL type or a int type or a boolean type with 0. So naturally it will become so.

which is why you need to specifically test for type. which is, ===

so the processor know you are referring specifically to a certain type.

that being said, any database that is in exisistance that uses auto increment id will NV use 0 as a valid first id. it will always be 1 first. so unless your "client" is storing every data in a flat text file and loading it into memory? its not very likely that 0 will EVER appear.

of course that said if you used database but disabled auto increment for the id,primary key den yes 0 is valid

edited Jan '15

this is not about databases, and it is not a php thing. And it's not specifically about IDs, it was just an example, and the situation where I became aware of the bug/issue. I am fully aware of the boolean comparison pecularities of php, this is not an issue in this case - or rather - it actually may seem to be but it shouldn't.

The value of zero is fully accessible through normal php methods. It is even available through phalcon itself with a little hacky trick. This is about how phalcon takes parameters/arguments delivered through the documented mechanisms and transfer them to the internal delivering mechanism. For some reason 0 is treated differently to all other numeric values.

simply put if I need to pass a value into a controller method:

/mycontroller/action/param

phalcon should not care what value param has, it should certainly not through it away all-together if is zero. That is

/mycontroller/action/5

Should be just as valid as

/mycontroller/action/0

EDIT here is an example that illustrates the issue (just put it in a class method):

Well, the original example was wrong, correcting it - which reveal an even more surprising detail: the last 0 is only removed if it's the only parameter. If there are two parameters, the last of the two is not removed even if it's 0.

Imagine a method with 2 optional parameters


public function editAction($var1=null,$var2=null)
{
    $result[] = $this->router->getMatches();
    $result[] = $this->router->getParams();
    echo "<pre>",print_r($result,true),"</pre>";
    // ... code dealing with none, one or two parameters
}

Now consider the following three urls:

    /namespace/controller/edit
    /namespace/controller/edit/0
    /namespace/controller/edit/0/0
    // /namespace/controller/edit
    // /namespace/controller/edit/0
    // (both lead to the same result)

    Array
    (
        [0] => Array
            (
                [0] => /all/usrstat/edit
                [1] => usrstat
                [2] => edit
            )

        [1] => Array
            (
            )

    )
    // /namespace/controller/edit/0/0

    Array
    (
        [0] => Array
            (
                [0] => /all/usrstat/edit/0/0
                [1] => usrstat
                [2] => edit
                [3] => /0/0
            )

        [1] => Array
            (
                [0] => 0
                [1] => 0
            )

    )

My current workaround for this method (if someone should be interested):


public function editAction($var1=null,$var2=null)
{
    if(is_null($var1)) {
        if(isset($this->router->getMatches()[3])) {
            // $var1 exists alone and must be 0 
            // remove first character (leading /)
            $var1 = substr($this->router->getMatches()[3],1);
        }
    }

    // ... code dealing with none, one or two parameters
}
edited Jan '15

Thanks for your suggestion. I should have said that I use v1.3.4 (just upgraded to v1.3.5 but I don't think there are any changes to this branch yet). I don't know if the issue exists in the v2.0 branch. I tried v2.0 but it broke my application and I don't have time to investigate right now. Perhaps some time next month.

But I will file a bug against v1.3.x later to day.

Perhaps you could explain how to submit a pull request. I've had this issue in another project where I couldn't figure out how and eventually gave up.



2.1k

base your branch off the latest commit in upstream. create the changes, and upload it to github, submit a pull request from that branch. if you plan to multiple changes, keep each changes that is related to a single branch.

feature1 = 1 branch feature2 = another branch

edited Jan '15

Test your case, and this issue also occur on my Phalcon install (version 2.0.0 Beta 3)

Imgur

But, when a route is defined i.e.

$router->add(
    '/movies/edit/{id:[0-9]+}',
    array(
        'controller' => 'movies',
        'action'     => 'edit'
    )
);

thie issue is gone

Hi Edi

About the router. Yes that would solve the situation with this specific controller/action, but it's a router defined like below. It matches a whole family of controllers and their actions. I have filed a bug (https://github.com/phalcon/cphalcon/issues/3274).

It did occur to me that it may be with the route matching but looking at the return value of router->getMatches() clearly shows the lost parameter is still there. It disappears later in the process.


    $router->add(
      "/mgmt/:controller/:action/:params",
      array(
        "namespace" => 'Ph002\Controllers\Management',
        "controller" => 1,
        "action" => 2,
        "params" => 3,
      )
    );