开发者

php null value confusion in switch statement

I have the following php code that gives me an unexpected result:

$foo = NULL;

switch($foo)
{
    case 0:
        print "What?!";
}

I'd expect the开发者_如何学运维 result to be nothing, but it matches case 0. The php manual says that NULL is a non-value, so how can it equal 0?


The switch statement applies loose comparison which means that the following things are treated as equivalent to 0:

false
0
"0"
NULL
"any string"
""


beacuse php is not type strict language

$foo = NULL;

if( isset( $foo ) ) {
    switch( $foo ) {
        case 0:
            print "WTF!!!";
    }
}


This can be also written like

$foo = NULL;

switch( true )
{
    case ( 0 === $foo ):
        print "What?!";
    default:
        print "Default?!";
}


PHP is doing a type-coerced, weak comparison. You will need to do this instead:

$foo = NULL;
if ($foo === 0)
    print "WTF!!!";


You can do what I did - it's lazy but it works. Before running the switch, I checked if the value is null and, if so, changed it to something known:

IF ($foo==null) {
     $foo == 99;
}
switch($foo)
{
    case 99:
        print "This is NULL"; break;
    case 0:
        print "What?!";
}


I'm assuming here, but it could be that the switch statement coerces the value of $foo when comparing to 0. To test this hypothesis, why don't you try adding this above the switch statement:

echo $foo == NULL;

This should echo 1 before the curse, if I'm correct...


EDIT: The inaccuracy is with my testing, and it was pointed out to me. Check the comments, if you are interested.

From what I've tested, the top answer is inaccurate. It seems as though a PHP switch statement sees NULL as a "joker", and applies any case to it. I tried with different numbers and with a string, and they all fired. Nothing there suggests it should be NULL, not even on PHP loose comparison. So my suggestion is adding a case NULL: at the start, just as you add default at the end.

    $foo = NULL;

    switch($foo)
    {
        case NULL:
            print "This is NULL"; break;
        case 0:
            print "What?!";
    }


As of PHP 8, you can use the match expression:

The match expression branches evaluation based on an identity check of a value.

Similarly to a switch statement, a match expression has a subject expression that is compared against multiple alternatives.

Unlike switch, it will evaluate to a value much like ternary expressions. Unlike switch, the comparison is an identity check (===) rather than a weak equality check (==).

Match expressions are available as of PHP 8.0.0.

Per your example:

$foo = null;

$value = match($foo) {
    0 => print('What?')
};

Will output:

Fatal error: Uncaught UnhandledMatchError: Unhandled match value of type null

So you can add a try/catch and handle it accordingly or add a default "catch-all":

$compare = null;

$value = match($compare) {
    0 => print('What?'),
    default => print('Default!')
};
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜