在 PHP 中使用 === 比较而不是 == 比较

Posted

技术标签:

【中文标题】在 PHP 中使用 === 比较而不是 == 比较【英文标题】:make switch use === comparison not == comparison In PHP 【发布时间】:2011-04-01 08:03:59 【问题描述】:

有没有办法让下面的代码仍然使用开关并返回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';

但对于更复杂的示例,这会变得冗长。

【问题讨论】:

【参考方案1】:

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

请注意,switch/case 的比较比较松散。

这意味着您必须想出一个解决方法。从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

【讨论】:

嗯,还有其他情况(不仅仅是 NULL)我希望它可以处理。【参考方案2】:

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

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

【讨论】:

【参考方案3】:

不。来自manual page:

请注意,switch/case 会执行loose comparison。

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

if (is_null($var))

  return 'a';


switch ($var)

    // ...

【讨论】:

【参考方案4】:

这是不可能的。

但是,您可以将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';

【讨论】:

到那时为什么还要麻烦开关呢?你甚至可以做 `switch (true) case $var === null: ... @ircmaxell,我认为 OP 想要通过逻辑或其他原因使用 switch,而不是有时进行严格检查。【参考方案5】:

也可以开启变量的类型:

switch (gettype($var)) 
...

【讨论】:

坏主意 - 来自文档:Never use gettype() to test for a certain type, since the returned string may be subject to change in a future version. In addition, it is slow too, as it involves string comparison. Instead, use the is_* functions. 如果 gettype() 发生变化,这会使函数变得无用并且语言的可靠性降低。使用 is_* 并不能回答有关开关的问题。其余的我同意:)【参考方案6】:

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

Switch documentation

Loose comparisons Docs, too

【讨论】:

您指的是您的经验还是文档?如果是后者,请发链接 您实际上 可以 使用 switch 执行此操作(请参阅我的回答),尽管我确实认为 if-else 更适合这项特定工作。 很多很好的答案,抱歉我只能选择 1。我选择了 if/elseif 谢谢大家。 实际上不是“总是” :) 如果不是所有 case 块都有 breakreturn 怎么办?【参考方案7】:

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

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

【讨论】:

【参考方案8】:

大概您正在打开变量并期待整数。为什么不简单地使用is_int($val) 预先检查变量的整数状态?

【讨论】:

【参考方案9】:

我只是用

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

如果留下以// 开头的评论,我认为这看起来仍然非常可读(最好删除以# 开头的评论)。

【讨论】:

【参考方案10】:

最好的方法之一是使用is_null检查NULL值

<?php
echo getValue();
function getValue()

    $var = 0;   
    switch(true) 
        case is_null($var) : return 'a'; break;
        default : return 'b'; break;
    

?>

【讨论】:

然而,最好的是=== null,因为它避免了不必要的函数调用开销。【参考方案11】:

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

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

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

【讨论】:

【参考方案12】:

从您的示例代码推断,我猜您有一堆常规情况和一个特殊情况(这里是null)。

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

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


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

也许还可以添加注释以记住 null 会意外匹配 0 大小写(也相反,0 将匹配 null 大小写)。

【讨论】:

【参考方案13】:

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

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

这也可以像这样处理更复杂的 switch 语句:

switch(true) 
    case $var === null:
        return 'a';
    case $var === 4:
    case $var === 'foobar':
        return 'b';
    default:
        return 'c';

【讨论】:

【参考方案14】:

创建一个类似断言的类,并在其中放入任何你想要的逻辑;只要“真”方法返回$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】:

如果您想同时测试变量的 valuetype,则构建一个包含这两个信息的新 string variable 并将其与如果您实现所有可能的类型(根据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'
?>

【讨论】:

【参考方案16】:

是的。在 PHP 8 上,您可以使用 match 语句来实现。

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

请看这里:https://www.php.net/manual/en/control-structures.match.php

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

【讨论】:

不错的建议!这是一个很难破解的问题;我猜match() 的唯一缺点是值必须是表达式,即1=&gt;'a';1=&gt;func();;但我不能做1=&gt;print("hello");print("world");,这是switch() 允许的。

以上是关于在 PHP 中使用 === 比较而不是 == 比较的主要内容,如果未能解决你的问题,请参考以下文章

Swoole协程与传统fpm同步模式比较

如何在php中检查当前的url,然后比较它是不是有一个特定的单词/短语

比较使用不同编码存储的相同值

何时使用 index.php 而不是 index.html

合并行(差异)是逐行比较,而不是一行与其他表的整行

是否有使用 C# 比较两个 PNG 图像的一部分而不是完整图像的功能?