Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unexpected PHP Switch Behavior

I was running some unit tests and ran across an unexpected behavior with a switch statement I was using. I've isolated the condition below.

function test($val)
{
    switch($val)
    {
       case 'a':
       case 'b':
          return 'first';
       break;
       case 'c':
          return 'second';
       break;
       default:
          return 'third';
    }
}

here are my first round of tests:

test('a') => 'first'
test('b') => 'first'
test('c') => 'second'
test('d') => 'third'    
test('0') => 'third'
test('1') => 'third'
test('true')  => 'third'
test('false') => 'third'

This is pretty self evident right? ok now check these out:

test(0)     => 'first'  // expected 'third'
test(1)     => 'third'
test(true)  => 'first'  // expected 'third'
test(false) => 'third'
test(null)  => 'third'
test([])    => 'third'

What's with the weird results with 0 and true? I would chalk it up to loose typing if 1/true and 0/false returned the same values. But they don't!

If I convert the value to a (string) then the switch works as intended.

test((string) 0)     => 'third'
test((string) 1)     => 'third'
test((string) true)  => 'third'
test((string) false) => 'third'

I don't understand why the switch wont "work" as I intended without using "(string)"

Can someone explain why this is happening?

like image 925
Eko3alpha Avatar asked Aug 04 '15 21:08

Eko3alpha


1 Answers

This is expected behavior. When doing comparisons, PHP will alter a value's type in its search for a match.

test(0)     => 'first'  // 'a' is altered into int 0 and therefore matches
var_dump((int) 'a'); // results 'int(0)'

test(true)  => 'first'  // both true and 'a' are truthy statements therefore matches.
if ('a' == true) echo "its true";

PHP is a weakly typed language and that bites you in the butt sometimes. You may consider re-factoring the switch into an if/else if/else structure and use the === operator for strong comparisons.

like image 105
dlporter98 Avatar answered Sep 29 '22 05:09

dlporter98