==和===的区别是什么?
松==比较究竟是如何工作的? 严格的===比较到底是如何工作的?
有什么有用的例子吗?
==和===的区别是什么?
松==比较究竟是如何工作的? 严格的===比较到底是如何工作的?
有什么有用的例子吗?
当前回答
<?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);
?>
其他回答
这都是关于数据类型的。以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)
因此,对于这种情况,您可以使用===来代替,以便检查数据类型。
==(相等)和===(完全相等)之间的差值
PHP提供了两个比较运算符来检查两个值是否相等。这两者之间的主要区别是'=='检查两个操作数的值是否相等。另一方面,'==='检查操作数的值以及操作数的类型是否相等。
= =(等于) ===(完全相等)
示例= >
<?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
?>
OR
<?php
$val1 = 1234;
$val2 = "1234";
var_dump($val1 === (int)$val2);// output => bool(true)
//First it checks type then operands value
?>
关于对象比较的其他答案的补充:
==使用对象的名称和它们的值来比较对象。如果两个对象具有相同的类型并且具有相同的成员值,$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
运算符==在两个不同类型之间进行类型强制转换,而===运算符执行“类型安全比较”。这意味着只有当两个操作数具有相同的类型和相同的值时,它才返回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数组和对象中,==和===之间有两个没有人提到的区别:两个具有不同键排序的数组和对象。
两个具有不同键排序的数组
如果你有两个数组,它们的键排序不同,但有相同的键值映射,它们是严格不同的(即使用===)。这可能会导致问题,如果你对一个数组进行键排序,并试图将排序后的数组与原始数组进行比较。
例如:
$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开始,引入了匿名类。在上面的测试中,新类{}和新stdClass()之间没有区别。