make switch use === comparison not == comparison In PHP
PhpType ConversionPhp Problem Overview
Is there anyway to make it so that the following code still uses a switch and returns b
not a
? Thanks!
$var = 0;
switch($var) {
case NULL : return 'a'; break;
default : return 'b'; break;
}
Using if statements, of course, you'd do it like this:
$var = 0;
if($var === NULL) return 'a';
else return 'b';
But for more complex examples, this becomes verbose.
Php Solutions
Solution 1 - Php
Sorry, you cannot use a ===
comparison in a switch statement, since according to the switch() documentation:
>Note that switch/case does loose comparison.
This means you'll have to come up with a workaround. From the loose comparisons table, you could make use of the fact that NULL == "0"
is false by type casting:
<?php
$var = 0;
switch((string)$var)
{
case "" : echo 'a'; break; // This tests for NULL or empty string
default : echo 'b'; break; // Everything else, including zero
}
// Output: 'b'
?>
Solution 2 - Php
Here is your original code in a "strict" switch statement:
switch(true) {
case $var === null:
return 'a';
default:
return 'b';
}
This can also handle more complex switch statement like this:
switch(true) {
case $var === null:
return 'a';
case $var === 4:
case $var === 'foobar':
return 'b';
default:
return 'c';
}
Solution 3 - Php
Not with switch
- it only does so called "loose" comparisons. You can always replace it with a if/else if
block, using ===
.
Solution 4 - Php
Yes. On PHP 8 you can do it with match
statement.
> Unlike switch, the comparison is an identity check (===) rather than a weak equality check (==). Match expressions are available as of PHP 8.0.0.
See here: https://www.php.net/manual/en/control-structures.match.php
$var=0;
echo match ($var) {
NULL=> 'a',
default => 'b'
};
Solution 5 - Php
Presumably you are switching on the variable and expecting integers. Why not simply check the integer status of the variable beforehand using is_int($val)
?
Solution 6 - Php
I had the same problem in a switch with string containing numbers ("15.2" is equal to "15.20" in a switch for php)
I solved the problem adding a letter before the text to compare
$var = '15.20';
switch ('#'.$var) {
case '#15.2' :
echo 'wrong';
break;
case '#15.20' :
echo 'right';
break;
}
Solution 7 - Php
> make switch use === comparison not == > comparison In PHP
Unfortunately switch
uses loose comparison and as far as I know there's no way to change that.
Solution 8 - Php
Nope. From the manual page:
>Note that switch/case does loose comparison.
If you only have two conditions, use an if
like your second example. Otherwise, check for NULL
first and switch on the other possibilities:
if (is_null($var))
{
return 'a';
}
switch ($var)
{
// ...
}
Solution 9 - Php
Switch statement in php does loose comparisons only (==) see http://www.php.net/manual/en/control-structures.switch.php
Use if/elseif/else if you need strict comparisons.
Solution 10 - Php
I just use
$var === null and $var = -1; // since switch is not type-safe
switch ( $var ) {
case 0:
# this tests for zero/empty string/false
break;
case -1:
# this tests for null
break;
}
I think this still looks very readable if the comment starting with //
is left behind (and the ones starting with #
are probably best deleted).
Solution 11 - Php
Extrapolating from your example code, I guess you have a bunch of regular cases and one special case (here, null
).
The simplest I can figure out is to handle this case before the switch:
if ($value === null) {
return 'null';
}
switch ($value) {
case 0:
return 'zero';
case 1:
return 'one';
case 2:
return 'two';
}
Maybe also add a comment to remember null
would unexpectedly match the 0
case (also the contrary, 0
would match a null
case).
Solution 12 - Php
This is not possible.
You can, however, put the if
statements inside the switch
:
switch($var) {
// Loose cases here
case 0:
if($var === NULL) {
return 'a';
}
// Fall through
default:
return 'b';
}
Or simply:
switch($var) {
// Loose cases here
default:
if($var === NULL) {
return 'a';
}
return 'b';
}
Solution 13 - Php
You can also switch on the type of the variable:
switch (gettype($var)) {
...
}
Solution 14 - Php
One of the best way is to check NULL value by using is_null
<?php
echo getValue();
function getValue()
{
$var = 0;
switch(true) {
case is_null($var) : return 'a'; break;
default : return 'b'; break;
}
}
?>
Solution 15 - Php
Create an assertion-like class and put whatever logic you want in it; so long as "true" methods return $this
(and nothing else to avoid false-positives.)
class Haystack
{
public $value;
public function __construct($value)
{
$this->value = $value;
}
public function isExactly($n)
{
if ($n === $this->value)
return $this;
}
}
$var = new Haystack(null);
switch ($var) {
case $var->isExactly(''):
echo "the value is an empty string";
break;
case $var->isExactly(null):
echo "the value is null";
break;
}
Or you can put your switch inside the actual class:
class Checker
{
public $value;
public function __construct($value)
{
$this->value = $value;
}
public function isExactly($n)
{
if ($n === $this->value)
return $this;
}
public function contains($n)
{
if (strpos($this->value, $n) !== false)
return $this;
}
public static function check($str)
{
$var = new self($str);
switch ($var) {
case $var->isExactly(''):
return "'$str' is an empty string";
case $var->isExactly(null):
return "the value is null";
case $var->contains('hello'):
return "'$str' contains hello";
default:
return "'$str' did not meet any of your requirements.";
}
}
}
var_dump(Checker::check('hello world')); # string(28) "'hello world' contains hello"
Of course that that point you might want to re-evaluate what you want to do with what you're checking and use a real validation library instead.
Solution 16 - Php
If you want to test both value and type of your variable, then build a new string variable containing both informations and compare it with your different scenarios (by concatenation) it should work for your case if you implement all possible types (according to gettype() documentation), example :
<?php
$var= 9999;
$valueAndTypeOfVar = (string)$var.' '.gettype($var);
switch($valueAndTypeOfVar) {
case "$var boolean" : echo 'a'; break;
case "$var integer" : echo 'b'; break;
case "$var double" : echo 'c'; break;
case "$var string" : echo 'd'; break;
case "$var array" : echo 'e'; break;
case "$var object" : echo 'f'; break;
case "$var resource" : echo 'g'; break;
case "$var NULL" : echo 'h'; break;
case "$var unknown type" : echo 'i'; break;
default: echo 'j'; break;
}
// Outputs: 'b'
?>