如果$ p == 1,PHP开关($ p)采用第一种情况

时间:2013-11-10 10:44:10

标签: php switch-statement

我有这段代码:

$r = do_something($data);
if ($r == 1) 
{
    echo "it is 1";
}

switch ($r) 
{
    case "a":
        print "a";
        break;

    case "b":
        print "b";
        break;

    default:
        print "default";
}

使用此代码,输出应为:

it is 1
default

但令人惊讶的是输出是:

it is 1
a

这怎么可能?

编辑:经过一些测试后我看到了:

$r === true. 

所以新的问题是:当var为true时,如何切换工作?

2 个答案:

答案 0 :(得分:2)

PHP的"type juggling"规则相当棘手,偶尔也不直观甚至引起争议。有a great big table in the manual显示当您对各种排序进行比较时会发生什么,但要解释您的具体情况:

  • 您正在使用三种不同的类型:$r目前是true,这是boolean; if语句针对1进行测试,integer;以及switch"a""b"进行string语句测试,boolean s。
  • 当您将integerinteger进行比较时,PHP首先使用boolean转换为{{0的规则将false转换为true 1}},以及其他任何内容都会转换为$r == 1。这会影响您true评估$r == 42的情况,但true 评估为boolean
  • 当您将stringstring进行比较时,会发生类似的事情,但此处string会根据此规则进行转换:空false为{{ 1}},其他任何内容都是true。因此$r == "a"在您的示例中也会计算为true,这就是执行switch语句的分支的原因。

要获得您希望的结果,您需要以不同的方式强制进行类型转换。有几种方法可以做到这一点,但最简单的方法是将$r转换为与您比较它的类型相同的类型:

  • (int)$r会为integer 1提供true的值,为0提供false,所以{{1} }会给出相同的结果,但更清楚的是if ( (int)$r == 1 )在代码中的那一点上实际上并不是$r
  • 更重要的是,integer会为您提供(string)$r string,因此"1"不必进行任何“类型杂耍”来比较{{1}等字符串1}}和switch( (string)$r ),你不会有任何惊喜。

答案 1 :(得分:0)

我认为你的do_something($data)函数如果按照预期的那样返回1。我尝试了这个代码,它的工作原理。在这里。

function do_something($data){
  return 1;
}

$r= do_something('abc');
if ($r == 1) 
{
  echo "it is 1<br />";
}
switch ($r) 
{
   case "a" : print "a"; break;
   case "b" : print "b"; break;
   default : print "default";
}

输出:

it is 1 
default