PHP: Comparing objects - Manual

downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

Классы и объекты (PHP 5) References inside the constructor

Last updated: Sat, 27 Jan 2007

view this page in

# Comparing objects

In PHP 4, objects are compared in a very simple manner, namely: Two object instances are equal if they have the same attributes and values, and are instances of the same class. Similar rules are applied when comparing two objects using the identity operator (`===`).

If we were to execute the code in the example below:

Пример 18-1. Example of object comparison in PHP 4

`<?php
function bool2str($bool) {
if ($bool === false) {
return 'FALSE';
} else {
return 'TRUE';
}
}
function compareObjects(&$o1, &$o2) {
echo 'o1 == o2 : '.bool2str($o1 == $o2)."\n";
echo 'o1 != o2 : '.bool2str($o1 != $o2)."\n";
echo 'o1 === o2 : '.bool2str($o1 === $o2)."\n";
echo 'o1 !== o2 : '.bool2str($o1 !== $o2)."\n";
}
class Flag {
var $flag;
function Flag($flag=true) {
$this->flag = $flag;
}
}
class SwitchableFlag extends Flag {
function turnOn() {
$this->flag = true;
}
function turnOff() {
$this->flag = false;
}
}
$o = new Flag();
$p = new Flag(false);
$q = new Flag();
$r = new SwitchableFlag();
echo "Compare instances created with the same parameters\n";
compareObjects($o, $q);
echo "\nCompare instances created with different parameters\n";
compareObjects($o, $p);
echo "\nCompare an instance of a parent class with one from a subclass\n";
compareObjects($o, $r);
?>`

Результат выполнения данного примера:

    Compare instances created with the same parameters
    o1 == o2 : TRUE
    o1 != o2 : FALSE
    o1 === o2 : TRUE
    o1 !== o2 : FALSE

    Compare instances created with different parameters
    o1 == o2 : FALSE
    o1 != o2 : TRUE
    o1 === o2 : FALSE
    o1 !== o2 : TRUE

    Compare an instance of a parent class with one from a subclass
    o1 == o2 : FALSE
    o1 != o2 : TRUE
    o1 === o2 : FALSE
    o1 !== o2 : TRUE

Which is the output we will expect to obtain given the comparison rules above. Only instances with the same values for their attributes and from the same class are considered equal and identical.

Even in the cases where we have object composition, the same comparison rules apply. In the example below we create a container class that stores an associative array of Flag objects.

Пример 18-2. Compound object comparisons in PHP 4

`<?php
class FlagSet {
var $set;
function FlagSet($flagArr = array()) {
$this->set = $flagArr;
}
function addFlag($name, $flag) {
$this->set[$name] = $flag;
}
function removeFlag($name) {
if (array_key_exists($name, $this->set)) {
unset($this->set[$name]);
}
}
}
$u = new FlagSet();
$u->addFlag('flag1', $o);
$u->addFlag('flag2', $p);
$v = new FlagSet(array('flag1'=>$q, 'flag2'=>$p));
$w = new FlagSet(array('flag1'=>$q));
echo "\nComposite objects u(o,p) and v(q,p)\n";
compareObjects($u, $v);
echo "\nu(o,p) and w(q)\n";
compareObjects($u, $w);
?>`

Результат выполнения данного примера:

    Composite objects u(o,p) and v(q,p)
    o1 == o2 : TRUE
    o1 != o2 : FALSE
    o1 === o2 : TRUE
    o1 !== o2 : FALSE

    u(o,p) and w(q)
    o1 == o2 : FALSE
    o1 != o2 : TRUE
    o1 === o2 : FALSE
    o1 !== o2 : TRUE

add a note User Contributed Notes
Comparing objects
magicturkey at gmail dot com
28-Mar-2006 07:15
`If youre just checking to see if the variables both reference the same object, instead of having a variable set up beforehand you could do away with the GLOBALS and have something like..
e.g.
<?php
class Foo {
var $serial;
function Foo() {
// Rest of constructor...
}
// Rest of class definition...
}
$baz->serial = -1;
$bar->serial = time();
if($bar->serial == $baz->serial) {
echo "Same";
}
?>`
pferlet at aston dot fr
29-Apr-2005 05:24
`Using globals isn't really well... you can use pattern singleton to verify this.`
jazfresh at hotmail dot com
08-Apr-2004 09:44
`An addendum to the post below:
If you are comparing two objects and you know that they will be of the same type (you're just not sure if they refer to the same object or not), then there is an easier and faster way to do the comparison, and this also avoids the infinite recursion problem with circular references described in the post below.
In the constructor of your object, set a "serial" attribute from a global variable that is incremented whenever a new object is created. Then you just have to compare serial numbers to see if the objects are the same.
e.g.
<?php
$FooSerial = 0;
class Foo {
var $serial;
function Foo() {
$this->serial = $GLOBALS['FooSerial']++;
// Rest of constructor...
}
// Rest of class definition...
}
if($bar->serial == $baz->serial) {
echo "Same";
}
?>`
jazfresh at hotmail dot com
07-Apr-2004 09:18
`PHP4 compares two objects (say, $a and $b) by comparing the type and all the attributes. If an attribute is an object, PHP4 will recursively call "if($a.attribute === $b.attribute)" to determine equality. However, this is a problem if a circular reference has been formed. The recursion will go on forever, and you will get the error message:
"Fatal error: Nesting level too deep - recursive dependency?"
Example, where the comparison will never terminate because PHP4 will forever recurse with comparisons of the attribute.
<?php
class Test {
var $obj;
}
$foo =& new Test;
$bar =& new Test;
$foo->obj =& $bar; // Make circular reference
$bar->obj =& $foo;
if($foo === $bar) {
baz();
}
?>
First PHP4 does ($foo === $bar), which expands into ($foo.obj === $bar.obj), which expands into ($bar.obj === $foo.obj), and so on and so on.
To avoid this situation, you must compare objects manually by comparing the two object's attributes and avoiding comparisons on attributes where a circular reference could arise.
This issue is easily avoided in PHP5, where objects can be compared via references rather than the object contents.`
add a note
Классы и объекты (PHP 5) References inside the constructor

Last updated: Sat, 27 Jan 2007
show source | credits | stats | sitemap | contact | advertising | mirror sites
Copyright © 2001-2007 The PHP Group
All rights reserved.
This mirror generously provided by: Yahoo! Inc.
Last updated: Sat Mar 10 09:32:46 2007 PST