0

我有这个代码:

$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 为真时,开关如何工作?

4

2 回答 2

2

PHP 的“类型杂耍”规则相当棘手,有时不直观,甚至有争议。手册中有一个很棒的大表,显示了当您进行各种比较时会发生什么,但要解释您的特殊情况:

  • 您正在使用三种不同的类型:$ris current true, which is a boolean; 该if语句针对1;integer进行测试 和switch语句测试"a""b",它们是strings。
  • 当您将 aboolean与 a 进行比较时integer,PHP 首先使用转换为 的规则将 a 转换integer为 a ,然后将其他任何内容转换为。这在您评估 to的情况下具有效果,但也会评估 to 。boolean0falsetrue$r == 1true$r == 42true
  • 当您将 aboolean与 a进行比较string时,会发生类似的事情,但这里的string根据此规则进行转换:空stringfalse,其他都是true。因此,在您的示例中$r == "a"也评估为true,这就是执行该switch语句分支的原因。

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

  • (int)$r将为您提供for和forinteger 1的值,因此将给出相同的结果,但更清楚的是,这实际上并不是代码中的那个点。true0falseif ( (int)$r == 1 )$rinteger
  • 更重要的是,(string)$r会给你string "1", 所以switch( (string)$r )不必做任何“类型杂耍”来比较像"a"and这样的字符串"b",你不会在那里得到任何惊喜。
于 2013-11-10T17:26:42.363 回答
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 
于 2013-11-10T10:54:53.637 回答