make switch使用===比较不==比较在PHP中

时间:2010-08-19 19:44:57

标签: php type-conversion

无论如何要使它以下代码仍然使用开关并返回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';

但是对于更复杂的例子,这变得冗长。

16 个答案:

答案 0 :(得分:48)

抱歉,您无法在switch语句中使用===比较,因为根据switch() documentation

  

请注意,开关/外壳的比较松散。

这意味着您必须提出一种解决方法。从the loose comparisons table开始,您可以通过类型转换来利用NULL == "0"为假的事实:

<?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'
?>

Live Demo

答案 1 :(得分:7)

不与switch - 它只进行所谓的“松散”比较。您始终可以使用if/else if替换===块。

答案 2 :(得分:4)

这是您在“严格”切换语句中的原始代码:

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;
}

答案 3 :(得分:3)

据推测,您正在切换变量并期望整数。为什么不事先使用is_int($val)

简单地检查变量的整数状态

答案 4 :(得分:3)

我在一个包含数字的字符串的开关中遇到了同样的问题(在PHP的开关中,“15.2”等于“15.20”)

我解决了在比较文本之前添加一个字母的问题

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

答案 5 :(得分:1)

  

使用开关===比较不==   PHP中的比较

不幸的是switch使用了松散的比较,据我所知,没有办法改变它。

答案 6 :(得分:1)

不。来自manual page

  

请注意,开关/案例loose comparison

如果您只有两个条件,请像第二个例子一样使用if。否则,首先检查NULL并启用其他可能性:

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

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

答案 7 :(得分:1)

php中的switch语句仅进行松散比较(==)请参阅http://www.php.net/manual/en/control-structures.switch.php

如果需要进行严格的比较,请使用if / elseif / else。

答案 8 :(得分:1)

我只是用

$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;
}

我认为如果以//开头的评论被遗忘(并且以#开头的评论最好被删除),这看起来仍然非常易读。

答案 9 :(得分:1)

是的。在PHP 8上,您可以使用match语句来完成此操作。

与切换不同,比较是身份检查(===),而不是弱相等检查(==)。匹配表达式自PHP 8.0.0起可用。

查看此处:https://www.php.net/manual/en/control-structures.match.php

$var=0;
echo match ($var) {
    NULL=> 'a',
    default => 'b'
};

答案 10 :(得分:0)

这是不可能的。

但是,您可以将if语句放在里面switch

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';
}

答案 11 :(得分:0)

您还可以打开变量的类型:

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

答案 12 :(得分:0)

最好的方法之一是使用is_null

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

答案 13 :(得分:0)

从您的示例代码推断,我猜您有一堆常规案例和一个特殊案例(此处为null)。

我能想到的最简单的方法是在切换之前处理这种情况:

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

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

也许还要添加评论以便记住null意外地匹配0案例(相反,0会匹配null案例。)

答案 14 :(得分:0)

创建一个类似断言的类,并将所需的任何逻辑放入其中;只要“ 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"

当然,在这一点上,您可能想重新评估要检查的内容,并使用真实的验证库。

答案 15 :(得分:0)

如果您要同时测试变量的类型,则构建一个包含两个信息的新的 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'
?>