web-dev-qa-db-ja.com

スイッチを使用する===比較しない==比較するPHP

とにかく次のコードがスイッチを使用し、bではなくaを返すようにすることはできますか?ありがとう!

$var = 0;
switch($var) {
    case NULL : return 'a'; break;
    default : return 'b'; break;
}

もちろん、ifステートメントを使用すると、次のようになります。

$var = 0;
if($var === NULL) return 'a';
else return 'b';

しかし、より複雑な例では、これは冗長になります。

74
Aaron Yodaiken

switch()ドキュメント によると、switchステートメントで===比較を使用できません。

スイッチ/ケースは緩やかな比較を行うことに注意してください。

つまり、回避策を考え出す必要があります。 緩やかな比較テーブル から、NULL == "0"が型キャストによってfalseであるという事実を利用できます:

<?php
$var = 0;
switch((string)$var) 
{
    case "" : echo 'a'; break; // This tests for NULL or empty string   
    default : echo 'b'; break; // Everything else, including zero
}
// Output: 'b'
?>

ライブデモ

49
Peter Ajtai

switchではありません-いわゆる「緩い」比較のみを行います。 if/else ifを使用して、いつでも===ブロックに置き換えることができます。

7
Adam Wright

これは、「厳密な」switch文の元のコードです。

switch(true) {
    case $var === null:
        return 'a';
    default:
        return 'b';
}

これは、次のようなより複雑なswitchステートメントも処理できます。

switch(true) {
    case $var === null:
        return 'a';
        break;
    case $var === 4:
    case $var === 'foobar':
        return 'b';
    default:
        return 'c';
        break;
}
5
thespacecamel

おそらく、変数をオンにして整数を期待しています。 is_int($val)を使用して、変数の整数ステータスを事前にチェックしないのはなぜですか?

3
Matt Esch

数字を含む文字列を持つスイッチで同じ問題が発生しました(phpのスイッチでは「15.2」は「15.20」に等しい)

比較するテキストの前に文字を追加する問題を解決しました

$var = '15.20';
switch ('#'.$var) {
    case '#15.2' :
      echo 'wrong';
    break;
    case '#15.20' :
      echo 'right';
    break;
}
3
caiofior

pHPでスイッチを使用===比較しない==比較する

残念ながら switch は緩やかな比較を使用しており、私が知る限りそれを変更する方法はありません。

1
quantumSoup

いいえ。 manual page から:

Switch/caseは 緩やかな比較 を行うことに注意してください。

2つの条件しかない場合は、2番目の例のようにifを使用します。それ以外の場合は、最初にNULLを確認し、他の可能性をオンにします。

if (is_null($var))
{
  return 'a';
}

switch ($var)
{
    // ...
}
1

Phpのswitchステートメントは緩い比較のみを行います(==)参照 http://www.php.net/manual/en/control-structures.switch.php

厳密な比較が必要な場合は、if/elseif/elseを使用します。

1
Esteban

使うだけ

$var === null and $var = -1; // since switch is not type-safe
switch ( $var ) {
    case 0:
        # this tests for zero/empty string/false
        break;
    case -1:
        # this tests for null
        break;
}

//で始まるコメントが残っている場合(および#で始まるコメントを削除することをお勧めします)、これは非常に読みやすいように見えます。

1
raveren

これは不可能です。

ただし、ifステートメントを配置することはできますinsideswitch

switch($var) {
    // Loose cases here

    case 0:
        if($var === NULL) {
            return 'a';
        }

        // Fall through

    default:
        return 'b';
}

または単に:

switch($var) {
    // Loose cases here

    default:
        if($var === NULL) {
            return 'a';
        }

        return 'b';
}
0
strager

最良の方法の1つは、is_nullを使用してNULL値をチェックすることです

<?php
echo getValue();
function getValue()
{
    $var = 0;   
    switch(true) {
        case is_null($var) : return 'a'; break;
        default : return 'b'; break;
    }
}
?>
0

変数のタイプをオンにすることもできます。

switch (gettype($var)) {
...
}
0
greg

変数のvaluetypeの両方をテストする場合は、両方の情報を含む新しいstring変数を作成し、さまざまなシナリオと(連結によって)比較します。可能なすべての型を実装すれば、ケースに応じて機能するはずです( gettype()documentation )に従って、例:

<?php
    $var= 9999;
    $valueAndTypeOfVar = (string)$var.' '.gettype($var);
    switch($valueAndTypeOfVar) {
        case "$var boolean" : echo 'a'; break;
        case "$var integer" : echo 'b'; break; 
        case "$var double" : echo 'c'; break;
        case "$var string" : echo 'd'; break; 
        case "$var array" : echo 'e'; break;
        case "$var object" : echo 'f'; break; 
        case "$var resource" : echo 'g'; break;
        case "$var NULL" : echo 'h'; break; 
        case "$var unknown type" : echo 'i'; break; 
        default: echo 'j'; break;
    }

   // Outputs: 'b'
?>

アサーションのようなクラスを作成し、必要なロジックをそれに入れます。 「true」メソッドが$thisを返す限り(そして誤検知を回避するために他に何もない。)

class Haystack
{
    public $value;

    public function __construct($value)
    {
        $this->value = $value;
    }

    public function isExactly($n)
    {
        if ($n === $this->value)
            return $this;
    }
}

$var = new Haystack(null);

switch ($var) {
    case $var->isExactly(''):
        echo "the value is an empty string";
        break;

    case $var->isExactly(null):
        echo "the value is null";
        break;
}

または、実際のクラス内にスイッチを配置することもできます。

class Checker
{
    public $value;

    public function __construct($value)
    {
        $this->value = $value;
    }

    public function isExactly($n)
    {
        if ($n === $this->value)
            return $this;
    }

    public function contains($n)
    {
        if (strpos($this->value, $n) !== false)
            return $this;
    }

    public static function check($str)
    {
        $var = new self($str);

        switch ($var) {
            case $var->isExactly(''):
                return "'$str' is an empty string";
            case $var->isExactly(null):
                return "the value is null";
            case $var->contains('hello'):
                return "'$str' contains hello";
            default:
                return "'$str' did not meet any of your requirements.";
        }
    }
}

var_dump(Checker::check('hello world'));   # string(28) "'hello world' contains hello"

もちろん、その時点で、確認したいことでやりたいことを再評価し、代わりに実際の検証ライブラリを使用することもできます。

0
user1718888

あなたのサンプルコードから外挿すると、通常のケースがたくさんあり、特別なケースが1つあると思います(ここではnull)。

私が理解できる最も簡単なことは、スイッチの前にこのケースを処理することです:

if ($value === null) {
    return 'null';
}

switch ($value) {
    case 0:
        return 'zero';
    case 1:
        return 'one';
    case 2:
        return 'two';
}

null0ケース(これとは逆に、0nullの場合と一致します)。

0
Gras Double