What is the difference between ==
and ===
?
==和==之间的区别是什么?
- How exactly does the loosely
==
comparison work? - 松散==比较到底是如何工作的?
- How exactly does the strict
===
comparison work? - 严格===比较到底是怎么回事?
What would be some useful examples?
有什么有用的例子吗?
19 个解决方案
#1
551
Difference between ==
and ===
The difference between the loosely ==
equal operator and the strict ===
identical operator is exactly explained in the manual:
松散=== =等算子和严格===等算子之间的区别在手册中有详细说明:
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. │ └──────────┴───────────┴───────────────────────────────────────────────────────────┘
Loosely ==
equal comparison
If you are using the ==
operator, or any other comparison operator which uses loosely comparison such as !=
, <>
or ==
, you always have to look at the context to see what, where and why something gets converted to understand what is going on.
如果您正在使用==操作符,或者使用松散比较的任何其他比较操作符,比如!=、<>或== =,那么您总是需要查看上下文来查看什么、在哪里以及为什么要转换某些内容以了解发生了什么。
Converting rules
- Converting to boolean
- 转换成布尔
- Converting to integer
- 转换成整数
- Converting to float
- 将浮动
- Converting to string
- 转换成字符串
- Converting to array
- 转换成数组
- Converting to object
- 转换成对象
- Converting to resource
- 将资源
- Converting to NULL
- 转换成空
Type comparison table
As reference and example you can see the comparison table in the manual:
作为参考和示例,您可以在手册中看到比较表:
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 ===
identical comparison
If you are using the ===
operator, or any other comparison operator which uses strict comparison such as !==
or ===
, then you can always be sure that the types won't magically change, because there will be no converting going on. So with strict comparison the type and value have to be the same, not only the value.
如果您正在使用===操作符,或者使用严格的比较操作符(如!==或=== === =),那么您可以始终确保类型不会神奇地改变,因为不会进行任何转换。所以严格地比较,类型和值必须是相同的,而不仅仅是值。
Type comparison table
As reference and example you can see the comparison table in the manual:
作为参考和示例,您可以在手册中看到比较表:
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 │ └─────────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴─────────┴───────┴───────┘
#2
226
The operator == casts between two different types if they are different, while the === operator performs a 'typesafe comparison'. That means that it will only return true if both operands have the same type and the same value.
如果两种类型不同,运算符==在它们之间强制转换,而===运算符执行“类型安全比较”。这意味着它只返回true,如果两个操作数具有相同的类型和相同的值。
Examples:
例子:
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
Warning: two instances of the same class with equivalent members do NOT match the ===
operator. Example:
警告:具有等效成员的同一个类的两个实例不匹配===运算符。例子:
$a = new stdClass();
$a->foo = "bar";
$b = clone $a;
var_dump($a === $b); // bool(false)
#3
37
In regards to JavaScript:
关于JavaScript:
The === operator works the same as the == operator, but it requires that its operands have not only the same value, but also the same data type.
===操作符的工作方式与==操作符相同,但它要求其操作数不仅具有相同的值,而且具有相同的数据类型。
For example, the sample below will display 'x and y are equal', but not 'x and y are identical'.
例如,下面的示例将显示“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');
}
#4
36
A picture is worth a thousand words:
一幅画胜过千言万语:
PHP Double Equals ==
equality chart:
PHP Triple Equals ===
Equality chart:
Source code to create these images:
创建这些图像的源代码:
https://github.com/sentientmachine/php_equality_charts
https://github.com/sentientmachine/php_equality_charts
Guru Meditation
Those who wish to keep their sanity, read no further.
那些想保持头脑清醒的人,不要再读下去了。
- '==' converts left and right operands to numbers when possible (123 == "123foo", but "123" != "123foo"
- " == "在可能的情况下将左右操作数转换为数字(123 = "123foo",但"123" != "123foo")
- A hex string in quotes is occasionally a float and will be casted to it against your will.
- 引号中的十六进制字符串有时是一个浮点数,将根据您的意愿被强制转换为它。
- == is not transitive because ("0" is == to 0, and 0 is == to "" but "0" != "")
- ==不具有传递性,因为("0" == = 0,0 == to " but "0" != ")
- "6" == " 6", "4.2" == "4.20", and "133" == "0133". But 133 != 0133, because 0133 is octal. But "0x10" == "16" and "1e3" == "1000"
- “6”= =“6”,“4.2”= =“4.20”,“133”= =“0133”。但是133 != 0133,因为0133是八进制的。但是"0x10" = "16"和"1e3" = "1000"
-
PHP Variables that have not been declared yet are false.
尚未声明的PHP变量是假的。
-
False is equal to 0, blankstring and empty array and "0".
False等于0,blankstring, empty array和0。
- When numbers are big enough they are == Infinity.
- 当数字足够大时,它们==∞。
-
NAN does not == itself, but it is True.
NAN不等于本身,但它是真的。
-
A fresh class is == to 1.
一个新的类== 1。
- False is the most dangerous value because False is == to most of the other variables, mostly defeating it's purpose.
- False是最危险的值,因为对于大多数其他变量来说,False是=,这通常会破坏它的目的。
Hope:
If you are using PHP, Thou shalt not use the double equals operator, always use triple equals.
如果你在使用PHP,你不应该使用双等号操作符,总是使用三重等号。
#5
19
An addition to the other answers concerning object comparison:
关于对象比较的其他答案的补充:
== compares objects using the name of the object and their values. If two objects are of the same type and have the same member values, $a == $b
yields true.
=使用对象的名称及其值对对象进行比较。如果两个对象具有相同的类型并且具有相同的成员值,$a == $b的值为真。
=== compares the internal object id of the objects. Even if the members are equal, $a !== $b
if they are not exactly the same object.
===比较对象的内部对象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
#6
11
In simplest terms:
用最简单的术语来描述:
== checks if equivalent (value only)
=检查是否相等(仅值)
=== checks if the same (value && type)
Equivalent vs. Same: An Analogy
===检查相同的(值&类型)是否相同:一个类比。
1 + 1 = 2 + 0 (equivalent)
1 + 1 = 2 + 0(等效)
1 + 1 = 1 + 1 (same)
In PHP:
在PHP中,1 + 1 = 1 + 1(相同):
true == 1 (true - equivalent in value)
真== 1(真-值相等)
true === 1 (false - not the same in value && type)
true === = 1 (false -值和类型不同)
- true is boolean
- 真正的是布尔
- 1 is int
- 1是int
#7
8
It's all about data types. Take a BOOL
(true or false) for example:
都是关于数据类型的。以BOOL(真或假)为例:
true
also equals 1
and false
also equals 0
true也等于1,false也等于0。
The ==
does not care about the data types when comparing: So if you had a variable that is 1 (which could also be true
):
==在比较时不关心数据类型:因此,如果有一个变量为1(也可以为真):
$var=1;
$ var = 1;
And then compare with the ==
:
然后与=比较:
if ($var == true)
{
echo"var is true";
}
But $var
does not actually equal true
, does it? It has the int value of 1
instead, which in turn, is equal to true.
但是$var并不等于true,对吧?它的int值是1,反过来也等于true。
With ===
, the data types are checked to make sure the two variables/objects/whatever are using the same type.
使用=== =检查数据类型,以确保使用相同类型的两个变量/对象/任何东西。
So if I did
如果我做了
if ($var === true)
{
echo "var is true";
}
that condition would not be true, as $var !== true
it only == true
(if you know what I mean).
这个条件是不正确的,因为$var !== true = true(如果你知道我的意思)。
Why would you need this?
你为什么需要这个?
Simple - let's take a look at one of PHP's functions: array_search()
:
简单—让我们看一下PHP的一个函数:array_search():
The array_search()
function simply searches for a value in an array, and returns the key of the element the value was found in. If the value could not be found in the array, it returns false. But, what if you did an array_search()
on a value that was stored in the first element of the array (which would have the array key of 0
)....the array_search()
function would return 0...which is equal to false..
函数的作用是:搜索数组中的一个值,返回该值所在元素的键。如果在数组中找不到该值,则返回false。但是,如果你做了一个函数()的值是存储在数组的第一个元素(将数组键(0)....函数的作用是:返回0…它等于。
So if you did:
所以如果你做:
$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.
}
So, do you see how this could be an issue now?
那么,你明白这是怎么回事了吗?
Most people don't use == false
when checking if a function returns false. Instead, they use the !
. But actually, this is exactly the same as using ==false
, so if you did:
大多数人在检查函数是否返回false时不使用== = false。相反,他们使用!但实际上,这和用==false是一样的,如果你这样做了
$arr = array("name");
if (!array_search("name", $arr)) // This is the same as doing (array_search("name", $arr) == false)
So for things like that, you would use the ===
instead, so that the data type is checked.
对于这样的东西,你可以使用===,这样就可以检查数据类型。
#8
8
One example is that a database attribute can be null or "":
一个例子是,一个数据库属性可以是null或"" ":
$attributeFromArray = "";
if ($attributeFromArray == ""){} //true
if ($attributeFromArray === ""){} //true
if ($attributeFromArray == null){} //true
if ($attributeFromArray === null){} //false
$attributeFromArray = null;
if ($attributeFromArray == ""){} //true
if ($attributeFromArray === ""){} //false
if ($attributeFromArray == null){} //true
if ($attributeFromArray === null){} //true
#9
6
Given x = 5
鉴于x = 5
1) Operator : == is "equal to". x == 8
is false
2) Operator : === is "exactly equal to" (value and type) x === 5
is true, x === "5"
is false
1)算子:==为“等于”。2)运算符:=== ===“正好等于”(值和类型)x === 5为真,x ==“5”为假
#10
3
$a = 5; // 5 as an integer
var_dump($a == 5); // compare value; return true
var_dump($a == '5'); // compare value (ignore type); return true
var_dump($a === 5); // compare type/value (integer vs. integer); return true
var_dump($a === '5'); // compare type/value (integer vs. string); return false
Be careful though. Here is a notorious problem.
不过要小心。这是一个臭名昭著的问题。
// 'test' is found at position 0, which is interpreted as the boolean 'false'
if (strpos('testing', 'test')) {
// code...
}
vs.
vs。
// true, as strict comparison was made (0 !== false)
if (strpos('testing', 'test') !== false) {
// code...
}
#11
3
In short, === works in the same manner that == does in most other programming languages.
简而言之,==的工作方式与==在大多数其他编程语言中的工作方式相同。
PHP allows you to make comparisons that don't really make sense. Example:
PHP允许你做一些没有意义的比较。例子:
$y = "wauv";
$x = false;
if ($x == $y)
...
While this allows for some interesting "shortcuts" you should beware since a function that returns something it shouldn't (like "error" instead of a number) will not get caught, and you will be left wondering what happened.
虽然这允许一些有趣的“快捷方式”,但是您应该小心,因为返回不应该返回的函数(比如“error”而不是数字)不会被捕捉到,您将会疑惑发生了什么。
In PHP, == compares values and performs type conversion if necessary (for instance, the string "12343sdfjskfjds" will become "12343" in an integer comparison). === will compare the value AND type and will return false if the type is not the same.
在PHP中,==将值进行比较,并在必要时执行类型转换(例如,字符串“12343sdfjskfjskfjjjds”在整数比较中将变成“12343”)。==将比较值和类型,如果类型不相同,则返回false。
If you look in the PHP manual, you will see that a lot of functions return "false" if the function fails, but they might return 0 in a successful scenario, which is why they recommend doing "if (function() !== false)" to avoid mistakes.
如果您查看PHP手册,您将看到如果函数失败,许多函数将返回“false”,但是在成功的场景中它们可能返回0,这就是为什么他们建议执行“If (function() != false)”以避免错误。
#12
3
Few of the examples
的一些例子
var_dump(5 == 5); // True
var_dump(5 == "5"); // True because == checks only same value not type
var_dump(5 === 5); // True
var_dump(5 === "5"); // False because value are same but data type are different.
P.S.
注:
== Compares the value only, it won't bother about the data types
==只对值进行比较,不会影响数据类型
vs.
vs。
=== Compares the values and data types
===比较值和数据类型
#13
2
You would use === to test whether a function or variable is false rather than just equating to false (zero or an empty string).
您可以使用===来测试函数或变量是否为false,而不只是将其等同于false(0或空字符串)。
$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;
}
In this case strpos would return 0 which would equate to false in the test
在这种情况下,strpos会返回0,这在测试中等于false
if ($pos == false)
or
或
if (!$pos)
which is not what you want here.
这不是你想要的。
#14
2
As for when to use one over the other, take for example the fwrite()
function in PHP.
至于何时使用其中一个函数,以PHP中的fwrite()函数为例。
This function writes content to a file stream. According to PHP, "fwrite()
returns the number of bytes written, or FALSE on error.". If you want to test if the function call was successful, this method is flawed:
此函数将内容写入文件流。根据PHP,“fwrite()返回写入的字节数,或错误的FALSE。”如果您想测试函数调用是否成功,这个方法是有缺陷的:
if (!fwrite(stuff))
{
log('error!');
}
It can return zero (and is considered successful), and your condition still gets triggered. The right way would be:
它可以返回0(被认为是成功的),并且您的条件仍然被触发。正确的做法是:
if (fwrite(stuff) === FALSE)
{
log('error!');
}
#15
2
PHP is a loosely typed language. Using the double equal operator allows for a loose checking of a variable.
PHP是一种松散类型的语言。使用双等运算符允许对变量进行松散检查。
Loosely checking a value would allow for some similar, but not equal, values to equate as the same:
松散地检查一个值将允许一些类似但不相等的值等同于相同:
- ''
- ”
- null
- 零
- false
- 假
- 0
- 0
All of these values would equate as equal using the double equal operator.
所有这些值都等于使用双相等运算符。
#16
1
Variables have a type and a value.
变量有类型和值。
- $var = "test" is a string that contain "test"
- $var = "test"是一个包含"test"的字符串
- $var2 = 24 is an integer vhose value is 24.
- $var2 = 24是一个整数v软管值为24。
When you use these variables (in PHP), sometimes you don't have the good type. For example, if you do
当您使用这些变量(在PHP中)时,有时您没有好的类型。例如,如果你这样做了
if ($var == 1) {... do something ...}
PHP have to convert ("to cast") $var to integer. In this case, "$var == 1" is true because any non-empty string is casted to 1.
PHP必须将$var转换为整型。在这种情况下,“$var == 1”是正确的,因为任何非空字符串都被强制为1。
When using ===, you check that the value AND THE TYPE are equal, so "$var === 1" is false.
当使用=== =时,您将检查值和类型是否相等,因此“$var === === 1”是假的。
This is useful, for example, when you have a function that can return false (on error) and 0 (result) :
这是有用的,例如,当您有一个函数可以返回false(错误)和0(结果):
if(myFunction() == false) { ... error on myFunction ... }
This code is wrong as if myFunction()
returns 0, it is casted to false and you seem to have an error. The correct code is :
这段代码是错误的,好像myFunction()返回0,它被强制为false,您似乎有一个错误。正确的代码是:
if(myFunction() === false) { ... error on myFunction ... }
because the test is that the return value "is a boolean and is false" and not "can be casted to false".
因为测试是返回值“是布尔值,是假的”而不是“可以被赋为假的”。
#17
1
The ===
operator is supposed to compare exact content equality while the ==
operator would compare semantic equality. In particular it will coerce strings to numbers.
===运算符应该比较确切的内容相等,而=运算符应该比较语义相等。特别是它将字符串强制为数字。
Equality is a vast subject. See the Wikipedia article on equality.
平等是一个巨大的课题。参见*关于平等的文章。
#18
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);
?>
#19
-1
All of the answers so far ignore a dangerous problem with ===. It has been noted in passing, but not stressed, that integer and double are different types, so the following code:
到目前为止,所有的答案都忽略了==的一个危险问题。它已经通过了,但是没有强调,整数和double是不同的类型,所以下面的代码:
$n = 1000;
$d = $n + 0.0e0;
echo '<br/>'. ( ($n == $d)?'equal' :'not equal' );
echo '<br/>'. ( ($n === $d)?'equal' :'not equal' );
gives:
给:
equal
not equal
Note that this is NOT a case of a "rounding error". The two numbers are exactly equal down to the last bit, but they have different types.
请注意,这不是一个“舍入错误”。这两个数完全相等,但它们有不同的类型。
This is a nasty problem because a program using === can run happily for years if all of the numbers are small enough (where "small enough" depends on the hardware and OS you are running on). However, if by chance, an integer happens to be large enough to be converted to a double, its type is changed "forever" even though a subsequent operation, or many operations, might bring it back to a small integer in value. And, it gets worse. It can spread - double-ness infection can be passed along to anything it touches, one calculation at a time.
这是一个令人讨厌的问题,因为如果所有的数字都足够小(“足够小”取决于您运行的硬件和操作系统),那么使用=== =的程序可以愉快地运行数年。然而,如果一个整数恰好足够大,可以转换为一个双精度浮点数,那么它的类型将被“永久”更改,即使后续的操作或许多操作可能会使它返回一个值为小整数。它变得更糟。它可以传播——双度感染可以传播到它接触到的任何地方,每次一个计算。
In the real world, this is likely to be a problem in programs that handle dates beyond the year 2038, for example. At this time, UNIX timestamps (number of seconds since 1970-01-01 00:00:00 UTC) will require more than 32-bits, so their representation will "magically" switch to double on some systems. Therefore, if you calculate the difference between two times you might end up with a couple of seconds, but as a double, rather than the integer result that occurs in the year 2017.
在现实世界中,这可能是处理2038年以后日期的程序的问题。此时,UNIX时间戳(从1970-01-01 00:00 UTC开始的秒数)将需要超过32位,因此在某些系统上,它们的表示将“神奇地”切换为双精度。因此,如果你计算两次的差值,你可能会得到几秒钟的时间,但结果是双倍的,而不是2017年出现的整数结果。
I think this is much worse than conversions between strings and numbers because it is subtle. I find it easy to keep track of what is a string and what is a number, but keeping track of the number of bits in a number is beyond me.
我认为这比字符串和数字之间的转换要糟糕得多,因为它很微妙。我发现很容易跟踪什么是字符串,什么是数字,但是跟踪一个数字中的位数是超出我的范围的。
So, in the above answers there are some nice tables, but no distinction between 1 (as an integer) and 1 (subtle double) and 1.0 (obvious double). Also, advice that you should always use === and never == is not great because === will sometimes fail where == works properly. Also, JavaScript is not equivalent in this regard because it has only one number type (internally it may have different bit-wise representations, but it does not cause problems for ===).
因此,在上面的答案中有一些很好的表,但是1(作为整数)和1(微妙的双精度)和1.0(明显的双精度)之间没有区别。同样,应该始终使用==和从不==的建议也不太好,因为==在==正常工作时有时会失败。此外,JavaScript在这方面并不等价,因为它只有一个数字类型(在内部它可能有不同的位级表示,但是它不会导致===的问题)。
My advice - use neither. You need to write your own comparison function to really fix this mess.
我的建议——不要用。您需要编写自己的比较函数来真正修复这一混乱。
#1
551
Difference between ==
and ===
The difference between the loosely ==
equal operator and the strict ===
identical operator is exactly explained in the manual:
松散=== =等算子和严格===等算子之间的区别在手册中有详细说明:
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. │ └──────────┴───────────┴───────────────────────────────────────────────────────────┘
Loosely ==
equal comparison
If you are using the ==
operator, or any other comparison operator which uses loosely comparison such as !=
, <>
or ==
, you always have to look at the context to see what, where and why something gets converted to understand what is going on.
如果您正在使用==操作符,或者使用松散比较的任何其他比较操作符,比如!=、<>或== =,那么您总是需要查看上下文来查看什么、在哪里以及为什么要转换某些内容以了解发生了什么。
Converting rules
- Converting to boolean
- 转换成布尔
- Converting to integer
- 转换成整数
- Converting to float
- 将浮动
- Converting to string
- 转换成字符串
- Converting to array
- 转换成数组
- Converting to object
- 转换成对象
- Converting to resource
- 将资源
- Converting to NULL
- 转换成空
Type comparison table
As reference and example you can see the comparison table in the manual:
作为参考和示例,您可以在手册中看到比较表:
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 ===
identical comparison
If you are using the ===
operator, or any other comparison operator which uses strict comparison such as !==
or ===
, then you can always be sure that the types won't magically change, because there will be no converting going on. So with strict comparison the type and value have to be the same, not only the value.
如果您正在使用===操作符,或者使用严格的比较操作符(如!==或=== === =),那么您可以始终确保类型不会神奇地改变,因为不会进行任何转换。所以严格地比较,类型和值必须是相同的,而不仅仅是值。
Type comparison table
As reference and example you can see the comparison table in the manual:
作为参考和示例,您可以在手册中看到比较表:
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 │ └─────────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴─────────┴───────┴───────┘
#2
226
The operator == casts between two different types if they are different, while the === operator performs a 'typesafe comparison'. That means that it will only return true if both operands have the same type and the same value.
如果两种类型不同,运算符==在它们之间强制转换,而===运算符执行“类型安全比较”。这意味着它只返回true,如果两个操作数具有相同的类型和相同的值。
Examples:
例子:
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
Warning: two instances of the same class with equivalent members do NOT match the ===
operator. Example:
警告:具有等效成员的同一个类的两个实例不匹配===运算符。例子:
$a = new stdClass();
$a->foo = "bar";
$b = clone $a;
var_dump($a === $b); // bool(false)
#3
37
In regards to JavaScript:
关于JavaScript:
The === operator works the same as the == operator, but it requires that its operands have not only the same value, but also the same data type.
===操作符的工作方式与==操作符相同,但它要求其操作数不仅具有相同的值,而且具有相同的数据类型。
For example, the sample below will display 'x and y are equal', but not 'x and y are identical'.
例如,下面的示例将显示“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');
}
#4
36
A picture is worth a thousand words:
一幅画胜过千言万语:
PHP Double Equals ==
equality chart:
PHP Triple Equals ===
Equality chart:
Source code to create these images:
创建这些图像的源代码:
https://github.com/sentientmachine/php_equality_charts
https://github.com/sentientmachine/php_equality_charts
Guru Meditation
Those who wish to keep their sanity, read no further.
那些想保持头脑清醒的人,不要再读下去了。
- '==' converts left and right operands to numbers when possible (123 == "123foo", but "123" != "123foo"
- " == "在可能的情况下将左右操作数转换为数字(123 = "123foo",但"123" != "123foo")
- A hex string in quotes is occasionally a float and will be casted to it against your will.
- 引号中的十六进制字符串有时是一个浮点数,将根据您的意愿被强制转换为它。
- == is not transitive because ("0" is == to 0, and 0 is == to "" but "0" != "")
- ==不具有传递性,因为("0" == = 0,0 == to " but "0" != ")
- "6" == " 6", "4.2" == "4.20", and "133" == "0133". But 133 != 0133, because 0133 is octal. But "0x10" == "16" and "1e3" == "1000"
- “6”= =“6”,“4.2”= =“4.20”,“133”= =“0133”。但是133 != 0133,因为0133是八进制的。但是"0x10" = "16"和"1e3" = "1000"
-
PHP Variables that have not been declared yet are false.
尚未声明的PHP变量是假的。
-
False is equal to 0, blankstring and empty array and "0".
False等于0,blankstring, empty array和0。
- When numbers are big enough they are == Infinity.
- 当数字足够大时,它们==∞。
-
NAN does not == itself, but it is True.
NAN不等于本身,但它是真的。
-
A fresh class is == to 1.
一个新的类== 1。
- False is the most dangerous value because False is == to most of the other variables, mostly defeating it's purpose.
- False是最危险的值,因为对于大多数其他变量来说,False是=,这通常会破坏它的目的。
Hope:
If you are using PHP, Thou shalt not use the double equals operator, always use triple equals.
如果你在使用PHP,你不应该使用双等号操作符,总是使用三重等号。
#5
19
An addition to the other answers concerning object comparison:
关于对象比较的其他答案的补充:
== compares objects using the name of the object and their values. If two objects are of the same type and have the same member values, $a == $b
yields true.
=使用对象的名称及其值对对象进行比较。如果两个对象具有相同的类型并且具有相同的成员值,$a == $b的值为真。
=== compares the internal object id of the objects. Even if the members are equal, $a !== $b
if they are not exactly the same object.
===比较对象的内部对象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
#6
11
In simplest terms:
用最简单的术语来描述:
== checks if equivalent (value only)
=检查是否相等(仅值)
=== checks if the same (value && type)
Equivalent vs. Same: An Analogy
===检查相同的(值&类型)是否相同:一个类比。
1 + 1 = 2 + 0 (equivalent)
1 + 1 = 2 + 0(等效)
1 + 1 = 1 + 1 (same)
In PHP:
在PHP中,1 + 1 = 1 + 1(相同):
true == 1 (true - equivalent in value)
真== 1(真-值相等)
true === 1 (false - not the same in value && type)
true === = 1 (false -值和类型不同)
- true is boolean
- 真正的是布尔
- 1 is int
- 1是int
#7
8
It's all about data types. Take a BOOL
(true or false) for example:
都是关于数据类型的。以BOOL(真或假)为例:
true
also equals 1
and false
also equals 0
true也等于1,false也等于0。
The ==
does not care about the data types when comparing: So if you had a variable that is 1 (which could also be true
):
==在比较时不关心数据类型:因此,如果有一个变量为1(也可以为真):
$var=1;
$ var = 1;
And then compare with the ==
:
然后与=比较:
if ($var == true)
{
echo"var is true";
}
But $var
does not actually equal true
, does it? It has the int value of 1
instead, which in turn, is equal to true.
但是$var并不等于true,对吧?它的int值是1,反过来也等于true。
With ===
, the data types are checked to make sure the two variables/objects/whatever are using the same type.
使用=== =检查数据类型,以确保使用相同类型的两个变量/对象/任何东西。
So if I did
如果我做了
if ($var === true)
{
echo "var is true";
}
that condition would not be true, as $var !== true
it only == true
(if you know what I mean).
这个条件是不正确的,因为$var !== true = true(如果你知道我的意思)。
Why would you need this?
你为什么需要这个?
Simple - let's take a look at one of PHP's functions: array_search()
:
简单—让我们看一下PHP的一个函数:array_search():
The array_search()
function simply searches for a value in an array, and returns the key of the element the value was found in. If the value could not be found in the array, it returns false. But, what if you did an array_search()
on a value that was stored in the first element of the array (which would have the array key of 0
)....the array_search()
function would return 0...which is equal to false..
函数的作用是:搜索数组中的一个值,返回该值所在元素的键。如果在数组中找不到该值,则返回false。但是,如果你做了一个函数()的值是存储在数组的第一个元素(将数组键(0)....函数的作用是:返回0…它等于。
So if you did:
所以如果你做:
$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.
}
So, do you see how this could be an issue now?
那么,你明白这是怎么回事了吗?
Most people don't use == false
when checking if a function returns false. Instead, they use the !
. But actually, this is exactly the same as using ==false
, so if you did:
大多数人在检查函数是否返回false时不使用== = false。相反,他们使用!但实际上,这和用==false是一样的,如果你这样做了
$arr = array("name");
if (!array_search("name", $arr)) // This is the same as doing (array_search("name", $arr) == false)
So for things like that, you would use the ===
instead, so that the data type is checked.
对于这样的东西,你可以使用===,这样就可以检查数据类型。
#8
8
One example is that a database attribute can be null or "":
一个例子是,一个数据库属性可以是null或"" ":
$attributeFromArray = "";
if ($attributeFromArray == ""){} //true
if ($attributeFromArray === ""){} //true
if ($attributeFromArray == null){} //true
if ($attributeFromArray === null){} //false
$attributeFromArray = null;
if ($attributeFromArray == ""){} //true
if ($attributeFromArray === ""){} //false
if ($attributeFromArray == null){} //true
if ($attributeFromArray === null){} //true
#9
6
Given x = 5
鉴于x = 5
1) Operator : == is "equal to". x == 8
is false
2) Operator : === is "exactly equal to" (value and type) x === 5
is true, x === "5"
is false
1)算子:==为“等于”。2)运算符:=== ===“正好等于”(值和类型)x === 5为真,x ==“5”为假
#10
3
$a = 5; // 5 as an integer
var_dump($a == 5); // compare value; return true
var_dump($a == '5'); // compare value (ignore type); return true
var_dump($a === 5); // compare type/value (integer vs. integer); return true
var_dump($a === '5'); // compare type/value (integer vs. string); return false
Be careful though. Here is a notorious problem.
不过要小心。这是一个臭名昭著的问题。
// 'test' is found at position 0, which is interpreted as the boolean 'false'
if (strpos('testing', 'test')) {
// code...
}
vs.
vs。
// true, as strict comparison was made (0 !== false)
if (strpos('testing', 'test') !== false) {
// code...
}
#11
3
In short, === works in the same manner that == does in most other programming languages.
简而言之,==的工作方式与==在大多数其他编程语言中的工作方式相同。
PHP allows you to make comparisons that don't really make sense. Example:
PHP允许你做一些没有意义的比较。例子:
$y = "wauv";
$x = false;
if ($x == $y)
...
While this allows for some interesting "shortcuts" you should beware since a function that returns something it shouldn't (like "error" instead of a number) will not get caught, and you will be left wondering what happened.
虽然这允许一些有趣的“快捷方式”,但是您应该小心,因为返回不应该返回的函数(比如“error”而不是数字)不会被捕捉到,您将会疑惑发生了什么。
In PHP, == compares values and performs type conversion if necessary (for instance, the string "12343sdfjskfjds" will become "12343" in an integer comparison). === will compare the value AND type and will return false if the type is not the same.
在PHP中,==将值进行比较,并在必要时执行类型转换(例如,字符串“12343sdfjskfjskfjjjds”在整数比较中将变成“12343”)。==将比较值和类型,如果类型不相同,则返回false。
If you look in the PHP manual, you will see that a lot of functions return "false" if the function fails, but they might return 0 in a successful scenario, which is why they recommend doing "if (function() !== false)" to avoid mistakes.
如果您查看PHP手册,您将看到如果函数失败,许多函数将返回“false”,但是在成功的场景中它们可能返回0,这就是为什么他们建议执行“If (function() != false)”以避免错误。
#12
3
Few of the examples
的一些例子
var_dump(5 == 5); // True
var_dump(5 == "5"); // True because == checks only same value not type
var_dump(5 === 5); // True
var_dump(5 === "5"); // False because value are same but data type are different.
P.S.
注:
== Compares the value only, it won't bother about the data types
==只对值进行比较,不会影响数据类型
vs.
vs。
=== Compares the values and data types
===比较值和数据类型
#13
2
You would use === to test whether a function or variable is false rather than just equating to false (zero or an empty string).
您可以使用===来测试函数或变量是否为false,而不只是将其等同于false(0或空字符串)。
$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;
}
In this case strpos would return 0 which would equate to false in the test
在这种情况下,strpos会返回0,这在测试中等于false
if ($pos == false)
or
或
if (!$pos)
which is not what you want here.
这不是你想要的。
#14
2
As for when to use one over the other, take for example the fwrite()
function in PHP.
至于何时使用其中一个函数,以PHP中的fwrite()函数为例。
This function writes content to a file stream. According to PHP, "fwrite()
returns the number of bytes written, or FALSE on error.". If you want to test if the function call was successful, this method is flawed:
此函数将内容写入文件流。根据PHP,“fwrite()返回写入的字节数,或错误的FALSE。”如果您想测试函数调用是否成功,这个方法是有缺陷的:
if (!fwrite(stuff))
{
log('error!');
}
It can return zero (and is considered successful), and your condition still gets triggered. The right way would be:
它可以返回0(被认为是成功的),并且您的条件仍然被触发。正确的做法是:
if (fwrite(stuff) === FALSE)
{
log('error!');
}
#15
2
PHP is a loosely typed language. Using the double equal operator allows for a loose checking of a variable.
PHP是一种松散类型的语言。使用双等运算符允许对变量进行松散检查。
Loosely checking a value would allow for some similar, but not equal, values to equate as the same:
松散地检查一个值将允许一些类似但不相等的值等同于相同:
- ''
- ”
- null
- 零
- false
- 假
- 0
- 0
All of these values would equate as equal using the double equal operator.
所有这些值都等于使用双相等运算符。
#16
1
Variables have a type and a value.
变量有类型和值。
- $var = "test" is a string that contain "test"
- $var = "test"是一个包含"test"的字符串
- $var2 = 24 is an integer vhose value is 24.
- $var2 = 24是一个整数v软管值为24。
When you use these variables (in PHP), sometimes you don't have the good type. For example, if you do
当您使用这些变量(在PHP中)时,有时您没有好的类型。例如,如果你这样做了
if ($var == 1) {... do something ...}
PHP have to convert ("to cast") $var to integer. In this case, "$var == 1" is true because any non-empty string is casted to 1.
PHP必须将$var转换为整型。在这种情况下,“$var == 1”是正确的,因为任何非空字符串都被强制为1。
When using ===, you check that the value AND THE TYPE are equal, so "$var === 1" is false.
当使用=== =时,您将检查值和类型是否相等,因此“$var === === 1”是假的。
This is useful, for example, when you have a function that can return false (on error) and 0 (result) :
这是有用的,例如,当您有一个函数可以返回false(错误)和0(结果):
if(myFunction() == false) { ... error on myFunction ... }
This code is wrong as if myFunction()
returns 0, it is casted to false and you seem to have an error. The correct code is :
这段代码是错误的,好像myFunction()返回0,它被强制为false,您似乎有一个错误。正确的代码是:
if(myFunction() === false) { ... error on myFunction ... }
because the test is that the return value "is a boolean and is false" and not "can be casted to false".
因为测试是返回值“是布尔值,是假的”而不是“可以被赋为假的”。
#17
1
The ===
operator is supposed to compare exact content equality while the ==
operator would compare semantic equality. In particular it will coerce strings to numbers.
===运算符应该比较确切的内容相等,而=运算符应该比较语义相等。特别是它将字符串强制为数字。
Equality is a vast subject. See the Wikipedia article on equality.
平等是一个巨大的课题。参见*关于平等的文章。
#18
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);
?>
#19
-1
All of the answers so far ignore a dangerous problem with ===. It has been noted in passing, but not stressed, that integer and double are different types, so the following code:
到目前为止,所有的答案都忽略了==的一个危险问题。它已经通过了,但是没有强调,整数和double是不同的类型,所以下面的代码:
$n = 1000;
$d = $n + 0.0e0;
echo '<br/>'. ( ($n == $d)?'equal' :'not equal' );
echo '<br/>'. ( ($n === $d)?'equal' :'not equal' );
gives:
给:
equal
not equal
Note that this is NOT a case of a "rounding error". The two numbers are exactly equal down to the last bit, but they have different types.
请注意,这不是一个“舍入错误”。这两个数完全相等,但它们有不同的类型。
This is a nasty problem because a program using === can run happily for years if all of the numbers are small enough (where "small enough" depends on the hardware and OS you are running on). However, if by chance, an integer happens to be large enough to be converted to a double, its type is changed "forever" even though a subsequent operation, or many operations, might bring it back to a small integer in value. And, it gets worse. It can spread - double-ness infection can be passed along to anything it touches, one calculation at a time.
这是一个令人讨厌的问题,因为如果所有的数字都足够小(“足够小”取决于您运行的硬件和操作系统),那么使用=== =的程序可以愉快地运行数年。然而,如果一个整数恰好足够大,可以转换为一个双精度浮点数,那么它的类型将被“永久”更改,即使后续的操作或许多操作可能会使它返回一个值为小整数。它变得更糟。它可以传播——双度感染可以传播到它接触到的任何地方,每次一个计算。
In the real world, this is likely to be a problem in programs that handle dates beyond the year 2038, for example. At this time, UNIX timestamps (number of seconds since 1970-01-01 00:00:00 UTC) will require more than 32-bits, so their representation will "magically" switch to double on some systems. Therefore, if you calculate the difference between two times you might end up with a couple of seconds, but as a double, rather than the integer result that occurs in the year 2017.
在现实世界中,这可能是处理2038年以后日期的程序的问题。此时,UNIX时间戳(从1970-01-01 00:00 UTC开始的秒数)将需要超过32位,因此在某些系统上,它们的表示将“神奇地”切换为双精度。因此,如果你计算两次的差值,你可能会得到几秒钟的时间,但结果是双倍的,而不是2017年出现的整数结果。
I think this is much worse than conversions between strings and numbers because it is subtle. I find it easy to keep track of what is a string and what is a number, but keeping track of the number of bits in a number is beyond me.
我认为这比字符串和数字之间的转换要糟糕得多,因为它很微妙。我发现很容易跟踪什么是字符串,什么是数字,但是跟踪一个数字中的位数是超出我的范围的。
So, in the above answers there are some nice tables, but no distinction between 1 (as an integer) and 1 (subtle double) and 1.0 (obvious double). Also, advice that you should always use === and never == is not great because === will sometimes fail where == works properly. Also, JavaScript is not equivalent in this regard because it has only one number type (internally it may have different bit-wise representations, but it does not cause problems for ===).
因此,在上面的答案中有一些很好的表,但是1(作为整数)和1(微妙的双精度)和1.0(明显的双精度)之间没有区别。同样,应该始终使用==和从不==的建议也不太好,因为==在==正常工作时有时会失败。此外,JavaScript在这方面并不等价,因为它只有一个数字类型(在内部它可能有不同的位级表示,但是它不会导致===的问题)。
My advice - use neither. You need to write your own comparison function to really fix this mess.
我的建议——不要用。您需要编写自己的比较函数来真正修复这一混乱。