Variable Comparison in PHP
You can code in PHP, use this framework, or that framework, but have you truly understood the meta behind it? Do you really grasp the falsy and truthy values, or the comparisons in PHP?
Do you really understand PHP?
Can you answer all the questions below?
Will the following operations return true or false?
** Note: The PHP version used is PHP 5.6 **
false == false // It will return true. Too easy, right ? :D
// But how about the following? TRUE or FALSE?
// Will the following comparisons return true or false?
1 == "1"
0 == "0"
"0" == "-0"
0 == false
"0" == false
"-0" == false
"0.0" == false
10 == "10tran duc thang 10"
"thang" == 0
"thang" == "0"
[] == false
null == []
null == ""
null == 0
null < -1
[] == 0
[] == ""
1 == "1 "
"1" == "1 "
"10" == " 10"
"100" == "1e2"
"1000" == "0x3e8"
"345" == "0345"
345 == 0345
"345" < "0346"
[1] == 1
(int) [1] == 1
(int) [0] == 0
false < -INF
false < NAN
true < INF
[1] == [1]
[1, 2] == [1 => 2, 0 => 1]
[1, 2] === [1 => 2, 0 => 1]
[1, 2] > 3
[1, 2] > "[1, 2]"
[1, 2] > [3]
[1, 2] > [2, 1]
(object) [1] > [1]
If you can answer all of these correctly and understand why it is the way it is, then you probably already understand what this article is about. Otherwise, take some time to read and explore the topics presented below, and you’ll find the explanation for each answer.
Variable Types
To answer the above questions, we first need to understand the data types in PHP.
Data Types in PHP
- String
- Integer (or Long)
- Float (or Double)
- Boolean
- Array
- Object
- NULL
- Resource
Things to Note
- The Boolean type has two values:
true
andfalse
- The Null type has only one value:
null
Just like in JavaScript and many other programming languages, to compare “equal” in PHP, we can use ==
and ===
===
Strict Comparison or Strict Equal will compare both the value and type of the two sides. If the types are different, the operation will return false
. The ===
operator is very straightforward and easy to use, causing less confusion for developers.
The ==
Loose Comparison or Loose Equal tries to convert both sides into the same value type and then performs the comparison.
You can use type casting similar to C to convert a variable from one type to another:
(boolean) 1 // true (string) 10 // "10" (int) "100" // 100 (int)[1] // 1
Falsy Values
The following values are considered false
when cast to a boolean:
false
0
0.0
""
(Empty string)"0"
[]
(Empty array)null
(Including unset variables)SimpleXML objects
(Created from empty tags)
For example:
0.0 == false; // true "0" == false; // true $a = new SimpleXML(''); $a == false; // true
Other than the above values, all other values are considered true
.
Comparisons in PHP
In this section, we will explore some special cases or rules when performing comparisons using ==
, <
, and >
in PHP.
Null vs String
null
is converted to an empty string.
null == ""; // true null == "0"; // false
Boolean & Null
- Variables compared with
boolean
ornull
are cast to boolean. - When comparing two
boolean
values,false
is less thantrue
.
NAN == true; // true null < NAN; // true "0" < true; // true
String vs String
- Comparing two strings using
==
may seem straightforward, but sometimes, strings are coerced toInteger
orFloat
. - For example,
"1" == "1.0"
returnstrue
, even though the strings are different (wtf, (facepalm)). - Even a string containing
e
or0x
can be coerced to a number if possible (facepalm).
"100" == "10e1"; // true "16" == "0x10"; // true
- If a string represents a number with spaces or tabs at the beginning, they will be ignored.
"1" == " 1"; // true "2" == " \t\n 2"; // true " 3" == "\t 3"; // true
- However, if spaces, tabs, or any other characters are at the end, they will not be coerced into a numeric value for comparison.
"1" == "1 "; // false "2" == "2a"; // false "3 " == "3 "; // false
- Comparing strings with
==
is very dangerous and can lead to many unexpected results, so don't use it when you're unsure of what you're doing =))
Number vs String
- Strings will be coerced into a numeric value (Integer or Float).
- If a string starts with a number, it will have that number's value.
- If a string does not start with a number, its value will be
0
.
0 == "thang"; // true 345 == "345 thang"; // true 100 == "10e1thang"; // true
Array vs Array
- Two arrays are considered "equal" using
==
if they have the same key-value pairs. The order of key-value pairs does not affect the comparison.
$array1 = ['3' => 3, '2' => 2, '1' => 1, '0' => 0]; $array2 = [false => '0', 1 => '1', 2 => '2', 3 => '3']; $array1 == $array2; // true $array1 === $array2; // false
- Two arrays are "equal" using
===
if they have the same key-value pairs and the order is the same.
$array1 = [0, 1, 3]; $array2 = [0, 2 => 3, 1 => 1]; $array3 = [0, 1 => 1, 2 => 3]; $array1 == $array2; // true $array1 == $array3; // true $array1 === $array2; // false $array1 === $array3; // true
- When comparing two arrays with
>
or<
, the array with more elements is considered greater. If two arrays have the same number of elements and matching keys, the comparison will proceed element by element. (If the keys differ, the comparison will returnfalse
.)
[1, 2] > [100000]; // true [1, 3] > [1, 2]; // true [1, 2] > [3 => 3]; // true [1 => 1] > [0 => 0]; // false
Object vs Object
- Instances of different classes cannot be compared.
- Objects are considered equal using
==
if they are instances of the same class and have the same attributes with equal values. - Objects are considered equal using
===
only if they refer to the same instance.
class C { public $c; public function __construct($c) { $this->c = $c; } } $a = new C("1"); $b = new C(1); $a == $b; // true $a === $b; // false $a = $b = new C(1); $a === $b; // true
Other
- An array is greater than
>
any other value that is not a boolean, array, or object. In other words, comparisons between arrays and integers, floats, strings, null, etc., will returntrue
, except when[] == null
, which returnstrue
, and thus[] > null
returnsfalse
. - An array can be coerced into a number, where an empty array has the value
0
, and all non-empty arrays have the value1
. - An object is greater than
>
an array.
[0] > 100; // true [1] > "thang"; // true (int) [null] == 1; // true (float) [] == 0; // true new stdClass > [1]; // true
Fun Fact
- The
==
operator in PHP is not reflexive, meaning$a == $a
is not always true. For example:NAN == NAN
will returnfalse
. - The
==
operator in PHP is symmetric, meaning$a == $b
and$b == $a
will return the same result. - The
==
operator in PHP is not transitive, meaning$a == $b
and$b == $c
may returntrue
, but$a == $c
may not.
1 == true; // true 2 == true; // true 1 == 2; // false
- The
<=
or>=
operators in PHP are not anti-symmetric, meaning$a <= $b
and$b <= $a
may both returntrue
, but$a == $b
might not.
NAN <= "thang"; // bool(true) "thang" <= NAN; // bool(true) NAN == "thang"; // bool(false)
- The
<=
or<
operators are not transitive. - The
<=
or<
operators are not total, meaning both$a <= $b
and$b <= $a
may returnfalse
, or even$a < $b
,$b < $a
, and$a == $b
can all happen.
NAN <= 0; // false 0 <= NAN; // false [0 => 1] > [1 => 0]; // false [0 => 1] < [1 => 0]; // false [0 => 1] == [1 => 0]; // false
- In version 7, PHP introduced a new operator
<=>
. The comparison$a <=> $b
will return -1 if$a < $b
, 0 if$a == $b
, and 1 if$a > $b
. - Perhaps you've used the Ternary Operation, the 3-way operator:
$x = $a ? $b : $c;
The operation $x = $a ? $a : $b;
can be shortened to $x = $a ?: $b;
- Also related to the Ternary Operation, what do you think the following operation will return?
true ? false : true ? false : true;
At first glance, you might think the result is false
with the order of operations as true ? (false) : (true ? false : true)
, but the correct order should be (true ? false : true) ? false : true
, and therefore, the operation will return true
.
Answers
Here are the answers to the questions posed at the beginning of the article.
If you've read through the above, you should understand why the answers come out the way they do. If there is a question you still don't understand the reason for, it means you missed something—just scroll up and read again (honho).
If you have any questions, feel free to leave a comment below.
false == false // It will return true. Too easy, right ? :D
// But how about the following? TRUE or FALSE?
// Will the following comparisons return true or false
1 == "1"; // true
0 == "0"; // true
"0" == "-0"; // true
0 == false; // true
"0" == false; // true
"-0" == false; // false
"0.0" == false; // false
10 == "10tran duc thang 10"; // true
"thang" == 0; // true
"thang" == "0"; // false
[] == false; // true
null == []; // true
null == ""; // true
null == 0; // true
null < -1; // true
[] == 0; // false
[] == ""; // false
1 == "1 "; // true
"1" == "1 "; // false
"10" == " 10"; // true
"100" == "1e2"; // true
"1000" == "0x3e8"; // true
"345" == "0345"; // true
345 == 0345; // false
"345" < "0346"; // true
[1] == 1; // false
(int) [1] == 1; // true
(int) [0] == 0; // false
false < -INF; // true
false < NAN; // true
true < INF; // false
[1] == [1]; // true
[1, 2] == [1 => 2, 0 => 1]; // true
[1, 2] === [1 => 2, 0 => 1]; // false
[1, 2] > 3; // true
[1, 2] > "[1, 2]"; // true
[1, 2] > [3]; // true
[1, 2] > [2, 1]; // false
(object) [1] > [1]; // true
The article may not cover all the edge cases of comparison operations in PHP. Also, much of it is based on personal experience and what I know. There might be areas lacking, and I hope to receive feedback from you.
Source: viblo.asia.