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

时间:2020-03-05 18:58:07  来源:igfitidea点击:

=====有什么区别?

  • 松散的" =="比较到底如何工作?
  • 严格的" ==="比较是如何工作的?

有什么有用的例子吗?

解决方案

回答

手册中完全解释了松散的=等于运算符和严格的equals等于运算符之间的区别:

Comparison Operators

┌──────────┬───────────┬───────────────────────────────────────────────────────────┐
│ 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

类型比较表

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

Loose comparisons with ==

┌─────────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬─────────┬───────┬───────┐
│         │ 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  │
└─────────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴─────────┴───────┴───────┘

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

类型比较表

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

Strict comparisons with ===

┌─────────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬─────────┬───────┬───────┐
│         │ 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  │
└─────────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴─────────┴───────┴───────┘

回答

我们将使用===来测试函数或者变量是否为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)

这不是我们想要的。

回答

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

回答

变量具有类型和值。

  • $ var =" test"是包含" test"的字符串
  • $ var2 = 24是一个整数,其值为24.

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

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

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

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

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

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

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

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

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

回答

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

回答

" ==="运算符应该比较精确的内容相等,而" =="运算符应该比较语义相等。特别是它将字符串强制转换为数字。

平等是一个广泛的主题。请参阅有关平等的维基百科文章。

回答

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

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

回答

至于何时在另一个之上使用,例如以PHP中的fwrite()函数为例。

此功能将内容写入文件流。根据PHP的说法,"fwrite()返回写入的字节数,如果出错则返回FALSE"。如果要测试函数调用是否成功,则此方法存在缺陷:

if (!fwrite(stuff))
{
    log('error!');
}

它可以返回零(并被认为是成功的),并且条件仍然被触发。正确的方法是:

if (fwrite(stuff) === FALSE)
{
    log('error!');
}

回答

简而言之,===的工作方式与==在大多数其他编程语言中的工作方式相同。

PHP使我们可以进行没有实际意义的比较。例子:

$y = "wauv";
$x = false;
if ($x == $y)
    ...

尽管这允许一些有趣的"快捷方式",但我们应该提防,因为返回不该返回的功能(例如"错误"而不是数字)的函数将不会被捕获,并且我们会想知道发生了什么。

在PHP中,==比较值并在必要时执行类型转换(例如,字符串" 12343sdfjskfjds"在整数比较中将变为" 12343")。 ===将比较值AND类型,如果类型不同,则返回false。

如果我们查看PHP手册,将会看到很多函数在函数失败时返回" false",但是在成功的情况下它们可能会返回0,这就是为什么他们建议这样做" if(function()!==错误)",以免出错。

回答

给定x = 5

1)运算子:==等于。 x == 8为假
2)运算子:===是"完全等于"(值和类型)x === 5为真,x ===" 5"为假