11

Today only I have noticed and found out the importance of using === operator. You can see it in the following example:

$var=0;
if ($var==false) echo "true"; else echo "false";  //prints true
$var=false;
if ($var==false) echo "true"; else echo "false";  //prints true
$var=0;
if ($var===false) echo "true"; else echo "false";  //prints false
$var=false;
if ($var===false) echo "true"; else echo "false";  //prints true 

The question is that, are there any situations where it is important to use === operator instead of using == operator?

Bakhtiyor
  • 7,198
  • 15
  • 55
  • 77
  • 4
    You could just say `echo $var == false;` etc. – Skilldrick Jun 21 '10 at 12:32
  • 1
    See http://stackoverflow.com/questions/1117967/what-does-mean – ChrisF Jun 21 '10 at 12:35
  • @Chris. I have look at that question already. But my question is about examples, where it is really important to consider using "===" operator, not "==" operator. – Bakhtiyor Jun 21 '10 at 12:38
  • 3
    @Skilldrick: No, you can't. PHP doesn't automatically convert boolean values to "true"/"false" strings. Your example would yield either `1` (for `true`) or the empty string (for `false`). The examples could be shortened, however, by using the ternary operator like so: `print ($var == false) ? 'true' : 'false';`. – Jakob Jun 21 '10 at 13:10
  • @Jakob: fair enough! Good point. – Skilldrick Jun 21 '10 at 21:26
  • One of my pet peeves in PHP, by the way. It makes quick-and-dirty debugging so much less quick and so much more dirty, when all you want is for `print true` to actually *print* true. – Jakob Jun 23 '10 at 18:36

9 Answers9

13

Of course, just one example: array_search()

Warning

This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE, such as 0 or "". Please read the section on Booleans for more information. Use the === operator for testing the return value of this function.

Basically if you use any function that returns a value on success but FALSE on failure, you should check the result with === to be sure (otherwise why would there be a big red warning box? ;))


Further examples: next(), current()
or as also mentioned string functions as strpos(), stripos(), etc.

Even substr() although it is not mentioned explicitly:

Returns the extracted part of string or FALSE on failure.

But what if the extracted part is"0"? It also evaluates to FALSE, but it is not an error.

Community
  • 1
  • 1
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • 1
    `next` and `current` are not good examples. What if there are *false* values like in `array(false)`? – Gumbo Jun 21 '10 at 13:07
  • 1
    @Gumbo: That's right. I just mentioned them because they also have this warning box in their documentation. But there is a note (that should be more emphasized imho): *Note: You won't be able to distinguish the end of an array from a boolean FALSE element. To properly traverse an array which may contain FALSE elements, see the each() function.* – Felix Kling Jun 21 '10 at 13:15
7

Always choose === over == except you're absolutely sure you need ==, because == is not transitive. And that in turn is important for your reasoning about your code.

Consider the following code snippet

if ( $a == $b && $b == $c ) {
    // [1] assert: $a == $c
}

Anybody would infer from the if condition that the assertion $a == $c is true because we are so used to the equality relation being transitive. But that doesn't hold for ==, counter example:

$a = "0";
$b = 0;
$c = null;

Now think about how often we make (at times unconsciously) that assumption while writing code. That could lead to serious bugs.

wnrph
  • 3,293
  • 4
  • 26
  • 38
6

In strpos() you have 0 when string is found and false when is misissing. You must use === to check difference.

Annika Backstrom
  • 13,937
  • 6
  • 46
  • 52
user372146
  • 61
  • 1
3

The === is strict type comparison operator, it will not only check values but also their type whereas == only checks whether or not values are same.

Consider a situation when you compare numbers or strings:

if (4 === 4) // same type and value
{
  // true
}

but

if (4 == "4") // same value but different type
{
  // true
}

and

if (4 === "4") // same value but different type
{
  // false
}

So in above cases, you have to make sensible choice whether to use == or ===

Sarfraz
  • 377,238
  • 77
  • 533
  • 578
3

A good example where you can get into trouble is comparing 0 and a string, fx

if (0 == 'completed') {
  // evaluates as TRUE
}

A string not starting with a number becomes 0 when converted into an int. This can become a problem when comparing a status that can be 0 to a string.

googletorp
  • 33,075
  • 15
  • 67
  • 82
2

The === operator checks type as well as value equality.

That's why 0 === false does not return true, as they are not of the same type.

Ian P
  • 12,840
  • 6
  • 48
  • 70
1

strpos($needle,$haystack) and related functions will return false if $needle doesn't exist in $haystack, and 0 if $needle is the first character of $haystack; and there's a whole host of similar functions. Using == can give you incorrect results in this case, so you should always use ===. The manual clarly identifies where this is necessary.

Mark Baker
  • 209,507
  • 32
  • 346
  • 385
0

I have recently ran into this problem myself when I was writing a quick SQL query parser. To cut the story short, I was comparing quoted parameters with their corner-case placeholders. Basically, the following code led me to some hard debugging times (the example is simplified of course)

$var = 0; // This is supplied dynamically

$someCondition = $var == '?';

$someCondition ended up being true all the time. Shiver

Basically any non-strict (==) <int> == <string> comparison will cause the string to be cast to an integer. Depending on the input, this might end up as 0 or the int-value of the string, if it has any, even if the whole string is not completely numeric.

Denis 'Alpheus' Cahuk
  • 4,152
  • 2
  • 23
  • 31
0

If you compare two numerical strings, they are compared as integers.1

var_dump("15" == "0xF"); // TRUE
var_dump("15" === "0xF"); // FALSE

and TRUE is indirectly equal to FALSE 2

$a = 0;
$b = 'x';
var_dump(FALSE == $a); // TRUE
var_dump($a == $b);  // TRUE
var_dump($b == TRUE);  // TRUE
var_dump(FALSE === $a); // FALSE
var_dump($a === $b);  // FALSE
var_dump($b === TRUE);  // FALSE
alexanderpas
  • 2,712
  • 2
  • 23
  • 33