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. 

したがって、新しい質問は次のとおりです。変数がtrueの場合、スイッチはどのように機能しますか?

4

2 に答える 2

2

PHP の「型ジャグリング」ルールはかなりトリッキーで、直感的でない場合があり、物議を醸すことさえあります。マニュアルには、さまざまな種類の比較を行ったときに何が起こるかを示す非常に大きな表がありますが、特定のケースを説明するために:

  • 3 つの異なるタイプで作業してい$rます。ステートメントは、;である に対してテストします。およびステートメントは、sであるandに対してテストします。truebooleanif1integerswitch"a""b"string
  • booleana と aを比較する場合integer、PHP は最初にを に変換するルールを使用してintegerを aに変換し、それ以外は に変換します。これは、 に評価される場合に効果がありますが、に評価されます。boolean0falsetrue$r == 1true$r == 42true
  • booleanaと aを比較するとstring、同様のことが起こりますが、ここでは、stringは次の規則に従って変換されます: 空のものstringは でありfalse、それ以外はtrueです。したがって、あなたの例で$r == "a"も評価されます。これが、ステートメントtrueのそのブランチが実行される理由です。switch

期待していた結果を得るには、別の方法で型変換を強制する必要があります。これを行うにはいくつかの方法がありますが、あなたのケースで最も簡単なのは、$r比較対象と同じ型にキャストすることです。

  • (int)$rfor 、およびforinteger 1の値が得られるため、同じ結果が得られますが、コードのその時点で実際には ではなかったことがより明確になります。true0falseif ( (int)$r == 1 )$rinteger
  • さらに重要なことに、(string)$rは を提供するstring "1"ので、やswitch( (string)$r )のような文字列と比較するために「型のジャグリング」を行う必要がなく、そこで驚くことはありません。"a""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 に答える