Hudzilla.org - the homepage of Paul Hudson
Contents > Objects Wish List | Report Bug | About Me ]

6.12     Comparing objects with == and ===

This is NOT the latest copy of this book; click here for the latest version.

When comparing objects, == and === may not work quite as you expect them to. If you were comparing two integers of the same value (eg 5), then == and === would both return true, however with objects == compares the objects' contents and === compares the objects' handles.

There is a difference there, and it's crucial: if you create an object and clone it, its clone will have exactly the same values as it. It will, therefore, return true for == as the two objects are the same in terms of their values. However, if you use ===, you will get false back because it compares the handles of the object and finds them to be different. This code example shows it nicely:

<?php
    
class foo { }

    
$wom = new foo();
    
$bat = clone $wom;

    print (int)(
$wom == $bat) . "\n";
    print (int)(
$wom === $bat) . "\n";
?>

That will output a 1 then a 0, as expected. Now, apart from basic comparison differences, this also matters because versions of PHP versioned 5.0.2 and earlier can encounter problems when doing an == comparison in very specific objects. Take a look at this code:

<?php
    
class foo {
        public function
__construct() {
            
$this->myself = $this;
        }
    }

    
$wom = new foo();
    
$bat = clone $wom;

    print (int)(
$wom == $bat) . "\n";
    print (int)(
$wom === $bat) . "\n";
?>

So, what we have there is a class that puts a reference to itself in the $myself variable on construction. Naturally, this is a silly thing to do, but the example is simplified - in a real scenario it might store a reference to another object that has a reference back to itself, which would cause the same problem. If you execute that script, you won't get 1 and 0. Instead, you'll get "PHP Fatal error: Nesting level too deep - recursive dependency?" Why? Because with ==, PHP compares each individual value of the object, so it looks at the value of $myself, finds it to be an object, looks inside it, finds $myself, looks inside it, finds $myself, etc, etc, etc, and carries on looping.

The solution to this is to use === in the comparison, which will allow PHP to compare object handles and therefore immediately tell that the two objects are identical. This has been fixed in newer versions of PHP.





<< 6.11 Copying objects   6.13 Saving objects: __sleep(), __wakeup(), and get_object_vars() >>
Table of Contents
Want to see this stuff in print? PHP in a Nutshell takes the core topics covered here, adds in thousands of edits from the editorial team and myself, and combines them to make an unbeatable reference for PHP programmers at all levels.



My latest book has hundreds more tips on how to use PHP, Apache, and MySQL, plus Perl, Python, shell scripts, performance tuning, and more!



Top-right shadow
 
Bottom-left shadow Bottom shadow

Comments from other readers
Alasdair - 05 Dec 2008

I executed the code above and had no problems. It output 1 and 0 rather than the "Fatal Error".
I thought it might be to do witht he fact that there is no $myself variable declared in the foo class but even after I added it the script still output 1 and 0.
Has anyone else found this?



Add comment
Please note that by posting a comment here you are committing it to the public domain. This is important so that others can make use of your code themselves, and also so that I can incorporate helpful notes directly into the main text. Comments are limited to 2000 characters in length.

If you are reporting an error in the content, please tell me directly.

Your name/email address:
Your comment:
 
Now, in order to verify that you're a real person, please answer this simple question: what is eight plus zero?
The answer is:
(please write in
numbers, eg 19)


Top-right shadow
 
Bottom-left shadow Bottom shadow