【问题标题】:How do the PHP equality (== double equals) and identity (=== triple equals) comparison operators differ?PHP 相等(== 双等)和身份(=== 三等)比较运算符有何不同?
【发布时间】:2010-09-09 23:41:42
【问题描述】:

===== 有什么区别?

  • 松散的== 比较究竟是如何工作的?
  • 严格的=== 比较究竟是如何工作的?

有哪些有用的例子?

【问题讨论】:

  • @BenAubin 说真的,您所做的编辑根本没有改善任何东西。
  • @BenAubin 我了解您想提供帮助,这很好,但这些编辑确实没有改善。现在,当您拥有足够数量的代表时,您的编辑将不会进入审核队列,因此请小心您的编辑。
  • @klutt 我的编辑是故意的。 OP 在要求 Javascript 和 PHP 的原始帖子的几分钟内进行了编辑,因此许多答案都引用了这两种语言。正如我在编辑说明中提到的,我的编辑带回了这个原始上下文。

标签: php


【解决方案1】:

===== 在 PHP 数组和对象中存在两个没有人提及的区别:两个具有不同键排序的数组和对象。

具有不同键排序的两个数组

如果您有两个数组,它们的键排序不同,但键值映射相同,则它们是完全不同的(即使用===)。如果您对数组进行键排序,并尝试将排序后的数组与原始数组进行比较,这可能会导致问题。

例如:

$arr1 = [
    "I" => "we",
    "you" => "you",
];

$arr2 = [
    "you" => "you",
    "I" => "we",
];

$arr1 == $arr2; // true
$arr1 === $arr2; // false

这里的一个典型陷阱是对一个数组执行ksort() 并将其与另一个数组进行严格比较。

对象

请记住,主要规则是两个不同的对象永远不会严格相等。看下面的例子:

$stdClass1 = new stdClass();
$stdClass2 = new stdClass();
$clonedStdClass1 = clone $stdClass1;

$stdClass1 == $stdClass2; // true
$stdClass1 === $stdClass2; // false
$stdClass1 == $clonedStdClass1; // true
$stdClass1 === $clonedStdClass1; // false

注意:将一个对象分配给另一个变量不会创建副本,而是创建对同一对象的引用。 See here.

注意:从 PHP7 开始,引入了anonymous classes。在上面的测试中,new class {}new stdClass() 没有区别。

【讨论】:

    【解决方案2】:

    ==(相等)和===(相等)的区别

    PHP 提供了两个比较运算符来检查两个值是否相等。这两者之间的主要区别在于'==' 检查两个操作数的值是否为equal or not。另一方面,'===' 检查值以及操作数的类型是equal or not

    ==(相等)

    ===(相等)

    示例 =>

    <?php 
        $val1 = 1234;
        $val2 = "1234";
        var_dump($val1 == $val2);// output => bool(true)
        //It checks only operands value
    ?> 
    
    
    <?php 
        $val1 = 1234;
        $val2 = "1234";
        var_dump($val1 === $val2);// output => bool(false)
        //First it checks type then operands value
    ?> 
    

    如果我们将 $val2 类型转换为 (int)$val2 或 (string)$val1 则返回 true

       <?php 
            $val1 = 1234;
            $val2 = "1234";
            var_dump($val1 === (int)$val2);// output => bool(true)
            //First it checks type then operands value
        ?> 
    

      <?php 
            $val1 = 1234;
            $val2 = "1234";
            var_dump($val1 === (int)$val2);// output => bool(true)
            //First it checks type then operands value
        ?> 
    

    【讨论】:

      【解决方案3】:

      PHP 双等于 ==

      在大多数编程语言中,比较运算符 (==) 一方面检查数据类型,另一方面检查变量内容是否相等。 PHP 中的标准比较运算符 (==) 的行为有所不同。这会在比较之前尝试将两个变量转换为相同的数据类型,然后才检查这些变量的内容是否相同。得到以下结果:

      <?php
          var_dump( 1 == 1 );     // true
          var_dump( 1 == '1' );   // true
          var_dump( 1 == 2 );     // false
          var_dump( 1 == '2' );   // false
          var_dump( 1 == true );  // true
          var_dump( 1 == false ); // false
      ?>
      

      PHP 三重等于 ===

      此运算符还检查变量的数据类型,并且仅当两个变量具有相同的内容和相同的数据类型时才返回 (bool)true。因此,以下是正确的:

      <?php
          var_dump( 1 === 1 );     // true
          var_dump( 1 === '1' );   // false
          var_dump( 1 === 2 );     // false
          var_dump( 1 === '2' );   // false
          var_dump( 1 === true );  // false
          var_dump( 1 === false ); // false
      ?>
      

      阅读更多What is the difference between == and === in PHP

      【讨论】:

        【解决方案4】:

        一张图抵千言:

        PHP 双等号== 等号图:

        PHP 三等号=== 等号图表:

        创建这些图像的源代码:

        https://github.com/sentientmachine/php_equality_charts

        上师冥想

        那些希望保持理智的人,不要再读下去了,因为这些都没有任何意义,只是说这就是 PHP 的疯狂分形的设计方式。

        1. NAN != NANNAN == true

        2. == 如果 left 是数字,则将左右操作数转换为数字。所以123 == "123foo",但是"123" != "123foo"

        3. 引号中的十六进制字符串有时是浮点数,并且会被意外强制转换为违背您的意愿,从而导致运行时错误。

        4. == 不能传递,因为"0"== 00 == """0" != ""

        5. 尚未声明的 PHP 变量为 false,尽管 PHP 有一种方法来表示未定义的变量,但该功能已被 == 禁用。

        6. "6" == " 6""4.2" == "4.20""133" == "0133"133 != 0133。但是"0x10" == "16""1e3" == "1000" 会在未经您的指示或同意的情况下将字符串转换为八进制,从而导致运行时错误。

        7. False == 0""[]"0"

        8. 如果将数字加 1 并且它们已经保持最大值,则它们不会回绕,而是将它们转换为 infinity

        9. 一个新的类是 == 到 1。

        10. False 是最危险的值,因为 False 对大多数其他变量来说是 ==,主要是违背了它的目的。

        希望:

        如果您使用的是 PHP,则不应使用双等号运算符,因为如果您使用三等号,唯一需要担心的极端情况是 NAN 和非常接近其数据类型最大值的数字,以至于它们被强制转换为无穷大。使用双等号,任何东西都可以让== 对任何东西感到惊讶,或者,或者可以违背您的意愿和!= 对显然应该相等的东西感到惊讶。

        您在 PHP 中使用 == 的任何地方都是一种不好的代码气味,因为其中的 85 个错误被隐式转换规则暴露出来,这些规则似乎是由数百万程序员通过布朗运动编程设计的。

        【讨论】:

        • 总是使用三等号真的是个好主意(也很安全)吗?
        • 是的,三等号的传递性使其更加安全和网络规模。
        • 一个数字怎么可能接近无穷大? [爆炸大脑 gif]
        • 值得注意的是1.0 !== 1,这可能有点棘手,例如floor(4 / 3) === 1 ? 'works as might be expected' : 'what?'
        • @EricLeschinski floor(4/3) === 1 不会评估为真,因为 floor 返回一个 float(即使返回值必须是一个整数,它不是按类型) - 因此有理由指出这个问题。 JavaScript 没有这个问题,因为只有一种数字类型(尽管因此存在整数舍入等其他问题)。
        【解决方案5】:

        到目前为止,所有答案都忽略了 === 的一个危险问题。顺便提一下,但不强调,integer 和 double 是不同的类型,所以下面的代码:

        $n = 1000;
        $d = $n + 0.0e0;
        echo '<br/>'. ( ($n ==  $d)?'equal' :'not equal' );
        echo '<br/>'. ( ($n === $d)?'equal' :'not equal' );
        

        给予:

         equal
         not equal
        

        请注意,这不是“舍入错误”的情况。这两个数字精确到最后一位,但它们的类型不同。

        这是一个令人讨厌的问题,因为如果所有数字都足够小,使用 === 的程序可以运行多年(其中“足够小”取决于您运行的硬件和操作系统)。但是,如果碰巧一个整数大到足以转换为双精度数,则它的类型将“永远”更改,即使后续操作或许多操作可能会将其恢复为较小的整数值。而且,情况会变得更糟。它可以传播——双重感染可以传递给它接触的任何东西,一次计算一次。

        在现实世界中,例如,在处理 2038 年之后的日期的程序中,这可能是一个问题。此时,UNIX 时间戳(自 1970-01-01 00:00:00 UTC 以来的秒数)将需要超过 32 位,因此它们的表示将“神奇地”在某些系统上切换为双倍。因此,如果您计算两次之间的差异,您可能会得到几秒钟的结果,但结果是双精度数,而不是 2017 年出现的整数结果。

        我认为这比字符串和数字之间的转换要糟糕得多,因为它很微妙。我发现跟踪什么是字符串和什么是数字很容易,但跟踪数字中的位数却超出了我的能力范围。

        因此,在上述答案中有一些不错的表格,但 1(作为整数)和 1(微妙的双精度)和 1.0(明显的双精度)之间没有区别。此外,建议您应该始终使用 === 而从不使用 == 并不是很好,因为 === 有时会在 == 正常工作的情况下失败。此外,JavaScript 在这方面并不等价,因为它只有一种数字类型(在内部它可能有不同的按位表示,但不会对 === 造成问题)。

        我的建议 - 两者都不使用。您需要编写自己的比较函数才能真正解决这个问题。

        【讨论】:

          【解决方案6】:

          运算符 == 在两种不同类型之间进行转换(如果它们不同),而 === 运算符执行“类型安全比较”。这意味着只有当两个操作数具有相同的类型和相同的值时,它才会返回 true。

          例子:

          1 === 1: true
          1 == 1: true
          1 === "1": false // 1 is an integer, "1" is a string
          1 == "1": true // "1" gets casted to an integer, which is 1
          "foo" === "foo": true // both operands are strings and have the same value

          警告:具有等效成员的同一类的两个实例与 === 运算符不匹配。示例:

          $a = new stdClass();
          $a->foo = "bar";
          $b = clone $a;
          var_dump($a === $b); // bool(false)
          

          【讨论】:

          • Nitpick:=== 仅当两个操作数的类型相同且值相等时才会返回 true =)
          • @gnud 这正是他在示例中显示的内容。如果它只是比较类型,那将不会被称为“类型比较”。
          • 在使用 PHP 8 年后,昨天是我第一次陷入应该使用的情况 ===
          • === 如果它们相等且类型相同,则为 true。 == 如果它们相等,则为 true。 != true 如果它们不相等。 !== 如果它们不相等或相等但类型不同,则为 true。
          • 另外,使用 === 比 == 稍快,因为它不需要在检查值是否相等之前进行转换。
          【解决方案7】:

          ===== 之间的区别

          松散的==相等运算符和严格的===相等运算符之间的区别在manual中有详细说明:

          比较运算符

          ┌──────────┬───────────┬──────────────────────── ──────────────────────────────────┐ │ 例子 │ 名称 │ 结果 │ ├──────────┼────────────┼──────────────────────── ──────────────────────────────────┤ │$a == $b │ 等于 │ 如果在类型杂耍之后 $a 等于 $b 则为 TRUE。 │ │$a === $b │ 相同 │ 如果 $a 等于 $b 并且它们属于同一类型,则为 TRUE。 │ └──────────┴───────────┴──────────────────────── ──────────────────────────────────┘

          松散==相等比较

          如果您使用== 运算符,或任何其他使用松散比较的比较运算符,例如!=&lt;&gt;==,您总是需要查看上下文 了解转换的内容、地点和原因,以了解正在发生的事情。

          转换规则

          类型对照表

          作为参考和示例,您可以在manual 中查看比较表:

          ==的松散比较

          ┌─────────┬────────┬────────┬───────┬───────┬──── ────┬────────┬────────┬────────┬────────┬──────────┬──── ────┬────────┐
          │ │ TRUE │ FALSE │ 1 │ 0 │ -1 │ "1" │ "0" │ "-1" │ NULL │ array() │ "php" │ "" │
          ├──────────┼────────┼────────┼────────┼────────┼──────── ┼────────┼────────┼────────┼────────┼──────────┼──────── ┼────────┤
          │ TRUE │ TRUE │ FALSE │ TRUE │ FALSE │ TRUE │ TRUE │ FALSE │ TRUE │ FALSE │ FALSE │ TRUE │ FALSE │
          │ FALSE │ FALSE │ TRUE │ FALSE │ TRUE │ FALSE │ FALSE │ TRUE │ FALSE │ TRUE │ TRUE │ FALSE │ TRUE │
          │ 1 │ TRUE │ FALSE │ TRUE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
          │ 0 │ FALSE │ TRUE │ FALSE │ TRUE │ FALSE │ FALSE │ TRUE │ FALSE │ TRUE │ FALSE │ TRUE │ TRUE │
          │ -1 │ TRUE │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │
          │ "1" │ TRUE │ FALSE │ TRUE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
          │ "0" │ FALSE │ TRUE │ FALSE │ TRUE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
          │ "-1" │ TRUE │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │
          │ NULL │ FALSE │ TRUE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ TRUE │ FALSE │ TRUE │
          │ array() │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ TRUE │ FALSE │ FALSE │
          │ "php" │ TRUE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │
          │ "" │ FALSE │ TRUE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ TRUE │
          └──────────┴───────┴────────┴────────┴────────┴──────── ┴────────┴────────┴────────┴────────┴──────────┴──────── ┴────────┘
          

          严格===相同比较

          如果您使用=== 运算符,或任何其他使用严格比较的比较运算符,例如!=====,那么您始终可以确保这些类型不会神奇地 em> 更改,因为不会进行转换。所以通过严格比较,类型和值必须相同,而不仅仅是值。

          类型对照表

          作为参考和示例,您可以在manual 中查看比较表:

          ===严格比较

          ┌─────────┬────────┬────────┬───────┬───────┬──── ────┬────────┬────────┬────────┬────────┬──────────┬──── ────┬────────┐
          │ │ TRUE │ FALSE │ 1 │ 0 │ -1 │ "1" │ "0" │ "-1" │ NULL │ array() │ "php" │ "" │
          ├──────────┼────────┼────────┼────────┼────────┼──────── ┼────────┼────────┼────────┼────────┼──────────┼──────── ┼────────┤
          │ TRUE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
          │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
          │ 1 │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
          │ 0 │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
          │ -1 │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
          │ "1" │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
          │ "0" │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │
          │ "-1" │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │ FALSE │
          │ NULL │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │ FALSE │
          │ array() │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │ FALSE │
          │ "php" │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │ FALSE │
          │ "" │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ FALSE │ TRUE │
          └──────────┴───────┴────────┴────────┴────────┴──────── ┴────────┴────────┴────────┴────────┴──────────┴──────── ┴────────┘
          

          【讨论】:

          • 有没有人觉得“000”==“0000”很奇怪?
          • 总是让我吃惊的是 false == array(),而 false == 0 但是 array() != 0,所以 false == array() !=/== 0?这让我感觉很奇怪。
          • @Pim ...继续:这样看:转换为 BOOL,任何值只需要落在两个边之一,truefalse。这很容易投。但是,出于所有实际目的,所有其他值实际上具有无限的组合。是"five" == 5array(0) == 0? array(0,0,0) == 0? 0.0000000000000000000000000000000000000000000000000001 == array()?
          • @Raithlin,小心数组。 Triple equals 为 javascript 中的不同数组提供 false,但为 PHP 提供 true,只要它们的值相等
          • @Raithlin,还有很多陷阱。 在 JavaScript 中: "000" != "00""000" == null"000" == false"0x0" == falsearray() == 0false != nullarray() != nullfalse == "0x0"false == "000"在 PHP 中,这是相反的行为: "000" == "00""000" != null"000" != false"0x0" != falsearray() != 0false == nullfalse == nullarray() == nullfalse != "0x0"false != "000"
          【解决方案8】:
          <?php
          
              /**
               * Comparison of two PHP objects                         ==     ===
               * Checks for
               * 1. References                                         yes    yes
               * 2. Instances with matching attributes and its values  yes    no
               * 3. Instances with different attributes                yes    no
               **/
          
              // There is no need to worry about comparing visibility of property or
              // method, because it will be the same whenever an object instance is
              // created, however visibility of an object can be modified during run
              // time using ReflectionClass()
              // http://php.net/manual/en/reflectionproperty.setaccessible.php
              //
              class Foo
              {
                  public $foobar = 1;
          
                  public function createNewProperty($name, $value)
                  {
                      $this->{$name} = $value;
                  }
              }
          
              class Bar
              {
              }
              // 1. Object handles or references
              // Is an object a reference to itself or a clone or totally a different object?
              //
              //   ==  true   Name of two objects are same, for example, Foo() and Foo()
              //   ==  false  Name of two objects are different, for example, Foo() and Bar()
              //   === true   ID of two objects are same, for example, 1 and 1
              //   === false  ID of two objects are different, for example, 1 and 2
          
              echo "1. Object handles or references (both == and    ===) <br />";
          
              $bar = new Foo();    // New object Foo() created
              $bar2 = new Foo();   // New object Foo() created
              $baz = clone $bar;   // Object Foo() cloned
              $qux = $bar;         // Object Foo() referenced
              $norf = new Bar();   // New object Bar() created
              echo "bar";
              var_dump($bar);
              echo "baz";
              var_dump($baz);
              echo "qux";
              var_dump($qux);
              echo "bar2";
              var_dump($bar2);
              echo "norf";
              var_dump($norf);
          
              // Clone: == true and === false
              echo '$bar == $bar2';
              var_dump($bar == $bar2); // true
          
              echo '$bar === $bar2';
              var_dump($bar === $bar2); // false
          
              echo '$bar == $baz';
              var_dump($bar == $baz); // true
          
              echo '$bar === $baz';
              var_dump($bar === $baz); // false
          
              // Object reference: == true and === true
              echo '$bar == $qux';
              var_dump($bar == $qux); // true
          
              echo '$bar === $qux';
              var_dump($bar === $qux); // true
          
              // Two different objects: == false and === false
              echo '$bar == $norf';
              var_dump($bar == $norf); // false
          
              echo '$bar === $norf';
              var_dump($bar === $norf); // false
          
              // 2. Instances with matching attributes and its values (only ==).
              //    What happens when objects (even in cloned object) have same
              //    attributes but varying values?
          
              // $foobar value is different
              echo "2. Instances with matching attributes  and its values (only ==) <br />";
          
              $baz->foobar = 2;
              echo '$foobar' . " value is different <br />";
              echo '$bar->foobar = ' . $bar->foobar . "<br />";
              echo '$baz->foobar = ' . $baz->foobar . "<br />";
              echo '$bar == $baz';
              var_dump($bar == $baz); // false
          
              // $foobar's value is the same again
              $baz->foobar = 1;
              echo '$foobar' . " value is the same again <br />";
              echo '$bar->foobar is ' . $bar->foobar . "<br />";
              echo '$baz->foobar is ' . $baz->foobar . "<br />";
              echo '$bar == $baz';
              var_dump($bar == $baz); // true
          
              // Changing values of properties in $qux object will change the property
              // value of $bar and evaluates true always, because $qux = &$bar.
              $qux->foobar = 2;
              echo '$foobar value of both $qux and $bar is 2, because $qux = &$bar' . "<br />";
              echo '$qux->foobar is ' . $qux->foobar . "<br />";
              echo '$bar->foobar is ' . $bar->foobar . "<br />";
              echo '$bar == $qux';
              var_dump($bar == $qux); // true
          
              // 3. Instances with different attributes (only ==)
              //    What happens when objects have different attributes even though
              //    one of the attributes has same value?
              echo "3. Instances with different attributes (only ==) <br />";
          
              // Dynamically create a property with the name in $name and value
              // in $value for baz object
              $name = 'newproperty';
              $value = null;
              $baz->createNewProperty($name, $value);
              echo '$baz->newproperty is ' . $baz->{$name};
              var_dump($baz);
          
              $baz->foobar = 2;
              echo '$foobar' . " value is same again <br />";
              echo '$bar->foobar is ' . $bar->foobar . "<br />";
              echo '$baz->foobar is ' . $baz->foobar . "<br />";
              echo '$bar == $baz';
              var_dump($bar == $baz); // false
              var_dump($bar);
              var_dump($baz);
          ?>
          

          【讨论】:

            【解决方案9】:

            这都是关于数据类型的。以BOOL(真或假)为例:

            true 也等于 1false 也等于 0

            == 在比较时不关心数据类型: 因此,如果您有一个为 1 的变量(也可以是 true):

            $var=1;

            然后与==比较:

            if ($var == true)
            {
                echo"var is true";
            }
            

            但是$var 实际上并不等于true,是吗?它的 int 值是 1,而它又等于 true。

            使用===,检查数据类型以确保两个变量/对象/任何东西使用相同的类型。

            如果我这样做了

            if ($var === true)
            {
                echo "var is true";
            }
            

            该条件不成立,因为 $var !== true 它只是 == true(如果你知道我的意思的话)。

            你为什么需要这个?

            简单——让我们看一下 PHP 的一个函数:array_search():

            array_search() 函数只是在数组中搜索一个值,并返回找到该值的元素的键。如果在数组中找不到该值,则返回 false。但是,如果您对存储在数组的第一个元素中的值执行array_search() 会怎样(数组键为0)......array_search()函数将返回 0...等于 false..

            如果你这样做了:

            $arr = array("name");
            if (array_search("name", $arr) == false)
            {
                // This would return 0 (the key of the element the val was found
                // in), but because we're using ==, we'll think the function
                // actually returned false...when it didn't.
            }
            

            那么,你现在明白这怎么可能是个问题了吗?

            大多数人在检查函数是否返回 false 时不使用== false。相反,他们使用!。但实际上,这与使用==false 完全相同,所以如果你这样做了:

            $arr = array("name");
            if (!array_search("name", $arr)) // This is the same as doing (array_search("name", $arr) == false)
            

            因此,对于这样的事情,您可以改用===,以便检查数据类型。

            【讨论】:

              【解决方案10】:

              关于 JavaScript:

              === 运算符的工作方式与 == 运算符相同,但它要求其操作数不仅具有相同的值,而且具有相同的数据类型。

              例如,下面的示例将显示“x 和 y 相等”,但不会显示“x 和 y 相同”。

              var x = 4;
              var y = '4';
              if (x == y) {
                  alert('x and y are equal');
              }
              if (x === y) {
                  alert('x and y are identical');
              }
              

              【讨论】:

              • @DavidThomas 不完全一样。见stackoverflow.com/questions/12598407/…
              • 我已经 DV 了这个答案,因为它是在 OP 的自我回答详细介绍了关于松散类型比较的相同见解 30 分钟后发布的。这个最初和当前带有 php 标记的问题的 javascript 答案确实应该被删除,但要这样做,投票数需要通过社区的努力来降低。换句话说,需要更多的 DV 才能进行适当的管理并删除此(已删除用户的)答案。
              【解决方案11】:

              关于对象比较的其他答案的补充:

              == 使用对象的名称及其值来比较对象。如果两个对象属于同一类型并具有相同的成员值,则$a == $b 将返回 true。

              === 比较对象的内部对象 id。即使成员相等,$a !== $b 如果它们不是完全相同的对象。

              class TestClassA {
                  public $a;
              }
              
              class TestClassB {
                  public $a;
              }
              
              $a1 = new TestClassA();
              $a2 = new TestClassA();
              $b = new TestClassB();
              
              $a1->a = 10;
              $a2->a = 10;
              $b->a = 10;
              
              $a1 == $a1;
              $a1 == $a2;  // Same members
              $a1 != $b;   // Different classes
              
              $a1 === $a1;
              $a1 !== $a2; // Not the same object
              

              【讨论】:

                【解决方案12】:

                变量有类型和值。

                • $var = "test" 是一个包含 "test" 的字符串
                • $var2 = 24 是一个整数 vhose 值是 24。

                当您使用这些变量时(在 PHP 中),有时您没有合适的类型。 例如,如果你这样做

                if ($var == 1) {... do something ...}
                

                PHP 必须将 ("to cast") $var 转换为整数。在这种情况下,“$var == 1”为真,因为任何非空字符串都被强制转换为 1。

                使用 === 时,您检查值和类型是否相等,因此 "$var === 1" 为假。

                这很有用,例如,当您有一个可以返回 false(错误)和 0(结果)的函数时:

                if(myFunction() == false) { ... error on myFunction ... }
                

                这段代码是错误的,好像myFunction() 返回 0,它被强制转换为 false,你似乎有错误。正确的代码是:

                if(myFunction() === false) { ... error on myFunction ... }
                

                因为测试是返回值“是布尔值并且为假”而不是“可以强制转换为假”。

                【讨论】:

                • 关于非空字符串,这实际上是不正确的。 "a" == 0 为真。
                【解决方案13】:

                您可以使用 === 来测试函数或变量是否为假,而不是仅仅等同于假(零或空字符串)。

                $needle = 'a';
                $haystack = 'abc';
                $pos = strpos($haystack, $needle);
                if ($pos === false) {
                    echo $needle . ' was not found in ' . $haystack;
                } else {
                    echo $needle . ' was found in ' . $haystack . ' at location ' . $pos;
                }
                

                在这种情况下,strpos 将返回 0,这相当于测试中的 false

                if ($pos == false)
                

                if (!$pos)
                

                这不是你想要的。

                【讨论】:

                  猜你喜欢
                  • 2011-07-23
                  • 2021-09-01
                  • 2011-06-11
                  • 2022-01-17
                  • 2020-12-10
                  相关资源
                  最近更新 更多