意外的PHP切换行为

Eko*_*pha 7 php switch-statement

我正在运行一些单元测试,并使用我正在使用的switch语句遇到了意外行为.我已经隔离了下面的条件.

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

这是我的第一轮测试:

test('a') => 'first'
test('b') => 'first'
test('c') => 'second'
test('d') => 'third'    
test('0') => 'third'
test('1') => 'third'
test('true')  => 'third'
test('false') => 'third'
Run Code Online (Sandbox Code Playgroud)

这很明显吧?好了,现在看看这些:

test(0)     => 'first'  // expected 'third'
test(1)     => 'third'
test(true)  => 'first'  // expected 'third'
test(false) => 'third'
test(null)  => 'third'
test([])    => 'third'
Run Code Online (Sandbox Code Playgroud)

什么是奇怪的结果与0和真?如果1/true和0/false返回相同的值,我会把它写成松散的输入.但他们没有!

如果我将值转换为(字符串),则交换机按预期工作.

test((string) 0)     => 'third'
test((string) 1)     => 'third'
test((string) true)  => 'third'
test((string) false) => 'third'
Run Code Online (Sandbox Code Playgroud)

我不明白为什么开关不会按照我的意图"工作"而不使用"(字符串)"

有人可以解释为什么会这样吗?

Hal*_*zed 2

根据 PHP 的文档:

请注意,switch/case 的比较松散。

http://php.net/manual/en/control-structs.switch.php

如果你想进行类型比较,你将需要重构你的代码。例子:

function test($val)
{
    if($val === 'a' || $val === 'b') 
        return 'first';

    if($val === 'c') 
        return 'second';

    return 'third';
}
Run Code Online (Sandbox Code Playgroud)

请注意我没有任何else's。这是因为每个语句都会返回一些东西...否则该函数将third默认返回。