Reputation: 11966
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?
Upvotes: 32
Views: 26361
Reputation: 14540
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!')
};
Upvotes: 1
Reputation: 11
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?!";
}
Upvotes: 1
Reputation: 152
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?!";
}
Upvotes: 0
Reputation: 461
This can be also written like
$foo = NULL;
switch( true )
{
case ( 0 === $foo ):
print "What?!";
default:
print "Default?!";
}
Upvotes: 5
Reputation: 11779
beacuse php is not type strict language
$foo = NULL;
if( isset( $foo ) ) {
switch( $foo ) {
case 0:
print "WTF!!!";
}
}
Upvotes: 7
Reputation: 17366
The switch
statement applies loose comparison which means that the following things are treated as equivalent to 0:
false
0
"0"
NULL
"any string"
""
Upvotes: 40
Reputation: 70324
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...
Upvotes: 0
Reputation: 81404
PHP is doing a type-coerced, weak comparison. You will need to do this instead:
$foo = NULL;
if ($foo === 0)
print "WTF!!!";
Upvotes: 1