==和===的区别是什么?

松==比较究竟是如何工作的? 严格的===比较到底是如何工作的?

有什么有用的例子吗?


当前回答

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

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

or

if (!$pos)

这不是你想要的。

其他回答

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

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

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

or

if (!$pos)

这不是你想要的。

一图胜千言万语:

PHP双等号==等号图表:

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

创建这些图像的源代码:

https://github.com/sentientmachine/php_equality_charts

大师冥想

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

NAN != NAN but NAN == true. == will convert left and right operands to numbers if left is a number. So 123 == "123foo", but "123" != "123foo" A hex string in quotes is occasionally a float, and will be surprise cast to float against your will, causing a runtime error. == is not transitive because "0"== 0, and 0 == "" but "0" != "" PHP Variables that have not been declared yet are false, even though PHP has a way to represent undefined variables, that feature is disabled with ==. "6" == " 6", "4.2" == "4.20", and "133" == "0133" but 133 != 0133. But "0x10" == "16" and "1e3" == "1000" exposing that surprise string conversion to octal will occur both without your instruction or consent, causing a runtime error. False == 0, "", [] and "0". If you add 1 to number and they are already holding their maximum value, they do not wrap around, instead they are cast to infinity. A fresh class is == to 1. False is the most dangerous value because False is == to most of the other variables, mostly defeating it's purpose.

希望:

如果你正在使用PHP,你不应该使用双等号操作符,因为如果你使用三等号,唯一需要担心的边缘情况是NAN和太接近其数据类型最大值的数字,它们会被强制转换为无穷大。使用双等号,任何东西都可以是surprise ==对任何东西或,或可以是出乎你的意愿和!=对显然应该是相等的东西。

在PHP中使用==的任何地方都是糟糕的代码气味,因为隐式强制转换规则暴露了85个错误,这些规则似乎是由数百万程序员通过布朗运动编程设计的。

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

True也等于1和 False也等于0

==在比较时不关心数据类型: 所以如果你有一个变量是1(这也可能是真的):

$ var = 1;

然后与==进行比较:

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

但$var并不等于true,对吧?它的int值为1,而int值为true。

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

如果我这样做了

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

这个条件不会为真,因为$var !== true它只== true(如果你知道我的意思)。

你为什么需要这个?

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

array_search()函数的作用是:简单地在数组中搜索一个值,并返回该值所在元素的键。如果在数组中找不到该值,则返回false。但是,如果对存储在数组的第一个元素(数组键值为0)....中的值执行array_search()会怎样呢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)

因此,对于这种情况,您可以使用===来代替,以便检查数据类型。

==和===的差值

松散==相等操作符和严格===相同操作符之间的区别在手册中有详细解释:

比较运算符

Example Name Result
$a == $b Equal TRUE if $a is equal to $b after type juggling.
$a === $b Identical TRUE if $a is equal to $b, and they are of the same type.

松散==相等比较

如果您正在使用==操作符,或任何其他使用松散比较的比较操作符,如!=,<>或==,您总是必须查看上下文,以了解转换的内容,位置和原因,以了解发生了什么。

转换规则

转换为布尔值 转换为整数 转换为浮点数 转换为字符串 转换为数组 转换为对象 转换为资源 转换为NULL

类型对照表

作为参考和例子,您可以在手册中看到比较表:

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

严格===相同的比较

如果您正在使用===操作符,或任何其他使用严格比较的比较操作符,如!==或===,那么您总是可以确保类型不会神奇地改变,因为不会发生转换。因此,在严格比较中,类型和值必须相同,而不仅仅是值。

类型对照表

作为参考和例子,您可以在手册中看到比较表:

严格比较===

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

编者注-这是正确的引用之前,但更可读作为降价表。这不是抄袭