PHP相等(==双重等于)和标识(===三次等于)比较运算符有何区别?

2020/09/25 07:21 · javascript ·  · 0评论

=====PHP 和有什么不一样

有什么有用的例子吗?


另外,这些运算符如何在JavaScript中使用?它们与PHP相关吗?

==之间的区别===

松散之间的差==等于操作员和严格===相同的运算符中被精确地说明手册

比较运算符

┌──────────┬──────────┬┬──────────────────── ──────────────────┐
│示例│名称│结果│
├──────────┼──────────┼────────────────────── ──────────────────┤
│$ a == $ b│相等│真,如果类型变戏后$ a等于$ b。
│$ a === $ b│相同│如果$ a等于$ b并且它们是同一类型,则为TRUE。
└──────────┴──────────┴┴──────────────────── ──────────────────┘

松散==相等的比较

如果您使用的是==运营商,或者松散的使用相比其他运营商相比,诸如!=<>或者==,你总是要看看上下文看什么,在哪里,为什么得到的东西转化为理解是怎么回事。

转换规则

类型比较表

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

松散的比较 ==

──────────┬──────┬────────┬────┬──────┬ ────────┬──────┬──────────┬ ┬────────┐
││TRUE│FALSE│1│0│-1│“ 1”│“ 0”│“ -1”│空│array()│“ php”│“”│
├──────────┼──────┼──────┼──────┼──────┼ ────────┼──────┼────────┼────┼──────┼ ┼────────┤
│TRUE│TRUE│FALSE│TRUE│FALSE│TRUE│TRUE│FALSE│TRUE│FALSE│FALSE│TRUE│FALSE│
│假│假│真│假│真│假│假│真│假│真│真│假│真│
│1│真│假│真│假│假│真│假│假│假│假│假│假│
│0│假│真│假│真│假│假│真│假│真│假│真│真│
│-1│真│假│假│假│真│假│假│真│假│假│假│假│假│
│“ 1”│真│假│真│假│假│真│假│假│假│假│假│假│假│
│“ 0”│否│正确│否│正确│否│假│真│假│假│假│假│假│假│
│“ -1”│是│假│假│假│真│假│假│真│假│假│假│假│假│
│空│假│真│假│真│假│假│假│假│假│真│真│假│真│
│数组()│假│真│假│假│假│假│假│假│假│真│真│假│假│假│
│“ php”│真│假│假│真│假│假│假│假│假│假│假│真│假│
│“”│假│是│假│真│假│假│假│假│假│真│假│假│真│
──────────┴──────┴────────┴────┴──────── ────────┴──────┴────────┴────────────── ┴────────┘

严格===相同的比较

如果您正在使用===运算符,或者使用严格比较的任何其他比较运算符(例如!==或)===,那么您始终可以确保类型不会发生神奇的变化,因为不会进行任何转换。因此,通过严格比较,类型和值必须相同,而不仅是值。

类型比较表

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

严格比较 ===

──────────┬──────┬────────┬────┬──────┬ ────────┬──────┬──────────┬ ┬────────┐
││TRUE│FALSE│1│0│-1│“ 1”│“ 0”│“ -1”│空│array()│“ php”│“”│
├──────────┼──────┼──────┼──────┼──────┼ ────────┼──────┼────────┼────┼──────┼ ┼────────┤
│TRUE│TRUE│FALSE│FALSE│FALSE│FALSE│FALSE│FALSE│FALSE│FALSE│FALSE│FALSE│FALSE│
│假│假│真│假│假│假│假│假│假│假│假│假│假│假│假│
│1│假│假│真│假│假│假│假│假│假│假│假│假│假│假│
│0│假│假│假│真│假│假│假│假│假│假│假│假│假│假│
│-1│假│假│假│假│真│假│假│假│假│假│假│假│假│
│“ 1”│假│假│假│假│假│真│假│假│假│假│假│假│假│
│“ 0”│假│假│假│假│假│假│真TRUE│假│假│假│假│假│假│
│“ -1”│假│假│假│假│假│假│假│假│是│假│假│假│假│假│
│空│假│假│假│假│假│假│假│假│假│真│假│假│假│假│
│数组()│假│假│假│假│假│假│假│假│假│假│真│假│假│假│
│“ php”│假│假│假│假│假│假│假│假│假│假│假│真│假│假│
│“”│假│假│假│假│假│假│假│假│假│假│假│假│假│正确│
──────────┴──────┴────────┴────┴──────── ────────┴──────┴────────┴────────────── ┴────────┘

如果==运算符不同,则它们在两种不同类型之间进行转换,而===运算符执行“类型安全比较”。这意味着只有两个操作数具有相同的类型和相同的值时,它才返回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)

一张图片胜过千言万语:

PHP Double Equals ==相等图:

在此处输入图片说明

PHP Triple Equals Equal ===图表:

在此处输入图片说明

创建这些图像的源代码:

https://github.com/sentientmachine/php_equality_charts

大师冥想

那些希望保持理智的人不再阅读,因为这些都没有任何意义,只说这是PHP的疯狂分形设计的目的。

  1. NAN != NAN但是NAN == true

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

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

  4. ==是不是因为传递"0"== 0,和0 == """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个错误,这些隐式转换规则似乎是由数百万程序员通过布朗运动编程的。

关于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');
}

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

==使用对象名称及其值比较对象。如果两个对象属于同一类型且成员值相同,则$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

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

true也等于1
false也等于0

比较时==,它们并不关心数据类型:因此,如果变量为1(也可能是true):

$var=1;

然后与==

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

但是$var实际上并不相等true吗?它具有int值,1int值等于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)

因此,对于类似的事情,您将使用===代替,以便检查数据类型。

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

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

这不是您想要的。

变量具有类型和值。

  • $ var =“ test”是包含“ test”的字符串
  • $ var2 = 24是整数,值为24。

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

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

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

使用===时,请检查值和THE TYPE是否相等,因此“ $ var === 1”为false。

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

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

该代码是错误的,好像myFunction()返回0,将其强制转换为false,并且您似乎有错误。正确的代码是:

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

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

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

到目前为止,所有答案都忽略了===的危险问题。顺便指出,但没有强调,整数和双精度型是不同的类型,因此以下代码:

$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在这方面也不等效,因为它只有一种数字类型(内部可能具有不同的按位表示形式,但是对于===不会造成问题)。

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

在PHP数组和对象之间==之间有两个区别===,我认为这里没有提到。具有不同键排序和对象的两个数组。

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

如果您有一个具有键排序的数组,而另一个数组具有不同的键排序,则它们是严格不同的(即,使用===)。如果您对数组进行键排序,然后尝试将排序后的数组与原始数组进行比较,则可能会导致这种情况。

例如,考虑一个空数组。首先,我们尝试将一些新索引推入数组,而不进行任何特殊排序。一个很好的例子是一个以字符串为键的数组。现在深入一个例子:

// Define an array
$arr = [];

// Adding unsorted keys
$arr["I"] = "we";
$arr["you"] = "you";
$arr["he"] = "they";

现在,我们有了一个未排序的键数组(例如,“他”紧跟在“您”之后)。考虑相同的数组,但是我们按字母顺序对键进行排序:

// Declare array
$alphabetArr = [];

// Adding alphabetical-sorted keys
$alphabetArr["I"] = "we";
$alphabetArr["he"] = "they";
$alphabetArr["you"] = "you";

提示:您可以使用ksort()函数按键对数组进行排序

现在您有了另一个数组,该数组的键排序与第一个数组不同。因此,我们将对其进行比较:

$arr == $alphabetArr; // true
$arr === $alphabetArr; // false

注意:这可能很明显,但是始终使用严格比较来比较两个不同的数组false但是,两个任意数组的使用===与否可能相等

您会说:“这种差异可以忽略不计”。然后我说这是有区别的,应该考虑并可能随时发生。如上所述,对数组中的键进行排序就是一个很好的例子。

对象

请记住,两个不同的对象从不严格相等这些示例将有助于:

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

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

注意:将对象分配给另一个变量不会创建副本,而是会创建对与该对象相同的内存位置的引用。看这里

注意:从PHP7开始,添加了匿名类从结果来看,有没有什么区别new class {},并new stdClass()在上面的测试。

本文地址:http://javascript.askforanswer.com/phpxiangdengshuangzhongdengyuhebiaoshisancidengyubijiaoyunsuanfuyouhequbie.html
文章标签: ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!