PHP的相等性(==双等号)和恒等性(===三等号)比较运算符有何不同?

577

==

===

之间有什么区别?
  • 宽松比较 == 是如何工作的?
  • 严格比较 === 是如何工作的?

有哪些有用的例子?


@BenAubin,说真的,你所做的修改并没有任何改进。 - klutt
@BenAubin 我知道你想要帮忙,这是好的,但那些编辑并没有真正改善东西。现在你已经有了足够的声望,你的编辑将不会进入审核队列,所以请小心处理你的编辑。 - klutt
@klutt 我的编辑是有意的。原帖发布几分钟后,OP进行了一次编辑,要求提供Javascript和PHP两种语言的答案,因此许多回答都涉及这两种语言。正如我在编辑说明中提到的那样,我的编辑恢复了这个原始上下文。 - Ben Aubin
13个回答

1
变量有类型和值。
  • $var = "test" 是一个包含 "test" 的字符串
  • $var2 = 24 是一个值为24的整数

当你使用这些变量(在PHP中),有时候你可能会得到错误的类型。 例如,如果你执行以下操作:

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

PHP需要将$var转换为整数。在这种情况下,"$var == 1"是真的,因为任何非空字符串都被转换为1。

当使用===时,您检查值和类型是否相等,所以"$var === 1"是假的。

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

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

这段代码是错误的,因为如果myFunction()返回0,则会被强制转换为false,你似乎有一个错误。正确的代码是:

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

因为测试的返回值是“布尔值且为false”,而不是“可以转换为false”。

关于非空字符串,实际上并不是这样的。"a" == 0 是TRUE。 - nickf

1

=====在PHP数组和对象中有两个区别,没有人提到:不同key排序的两个数组和对象。

不同key排序的两个数组

如果你有两个键按不同顺序排列的数组,但它们具有相等的键值映射,则它们是严格不同的(即使用===)。这可能会导致问题,如果你对一个数组进行key排序,并尝试将排序后的数组与原始数组进行比较。

例如:

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

$arraySorted = $arrayUnsorted;
ksort($arraySorted);

$arrayUnsorted == $arraySorted; // true
$arrayUnsorted === $arraySorted; // false

对象

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

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

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

注意:将一个对象分配给另一个变量并不会创建副本,而是创建对同一对象的引用。在这里查看

注意:从PHP7开始,匿名类被引入。在上述测试中,new class {}new stdClass()之间没有区别。


1
<?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);
?>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接