make switch use === comparison not == comparison In PHP

PhpType Conversion

Php 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'
?>

Live Demo

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'
?>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAaron YodaikenView Question on Stackoverflow
Solution 1 - PhpPeter AjtaiView Answer on Stackoverflow
Solution 2 - PhpthespacecamelView Answer on Stackoverflow
Solution 3 - PhpAdam WrightView Answer on Stackoverflow
Solution 4 - PhpzviView Answer on Stackoverflow
Solution 5 - PhpMatt EschView Answer on Stackoverflow
Solution 6 - PhpcaiofiorView Answer on Stackoverflow
Solution 7 - PhpquantumSoupView Answer on Stackoverflow
Solution 8 - PhpDaniel VandersluisView Answer on Stackoverflow
Solution 9 - PhpEstebanView Answer on Stackoverflow
Solution 10 - PhpraverenView Answer on Stackoverflow
Solution 11 - PhpGras DoubleView Answer on Stackoverflow
Solution 12 - PhpstragerView Answer on Stackoverflow
Solution 13 - PhpgregView Answer on Stackoverflow
Solution 14 - PhpPrem Kumar MauryaView Answer on Stackoverflow
Solution 15 - Phpuser1718888View Answer on Stackoverflow
Solution 16 - PhpMohamed Ayoub BENJELLOUNView Answer on Stackoverflow