|
Comparing objectsIn PHP 5, object comparison is more complicated than in PHP 4 and more in accordance to what one will expect from an Object Oriented Language (not that PHP 5 is such a language).
When using the comparison operator (
On the other hand, when using the identity operator ( An example will clarify these rules. Example 10.32. Example of object comparison in PHP 5<?php The above example will output: Two instances of the same class
Note:
Extensions can define own rules for their objects comparison. Code Examples / Notes » language.oop5.object_comparisonrune
Whoops, apparently I hadn't checked the array-part of the below very well. Forgot to test if the arrays had same length, and had some misaligned parenthesis. This one should work better :+) <? function deepCompare($a,$b) { if(is_object($a) && is_object($b)) { if(get_class($a)!=get_class($b)) return false; foreach($a as $key => $val) { if(!deepCompare($val,$b->$key)) return false; } return true; } else if(is_array($a) && is_array($b)) { while(!is_null(key($a)) && !is_null(key($b))) { if (key($a)!==key($b) || !deepCompare(current($a),current($b))) return false; next($a); next($b); } return is_null(key($a)) && is_null(key($b)); } else return $a===$b; } ?> jazfresh
Note that when comparing object attributes, the comparison is recursive (at least, it is with PHP 5.2). That is, if $a->x contains an object then that will be compared with $b->x in the same manner. Be aware that this can lead to recursion errors: <?php class Foo { public $x; } $a = new Foo(); $b = new Foo(); $a->x = $b; $b->x = $a; print_r($a == $b); ?> Results in: PHP Fatal error: Nesting level too deep - recursive dependency? in test.php on line 11 dionyziz
Note that classes deriving from the same parent aren't considered equal when comparing even using ==; they should also be objects of the same child class. <?php class Mom { private $mAttribute; public function Mom( $attribute ) { $this->mAttribute = $attribute; } public function Attribute() { return $this->mAttribute; } } final class Sister extends Mom { public function Sister( $attribute ) { $this->Mom( $attribute ); } } final class Brother extends Mom { public function Brother( $attribute ) { $this->Mom( $attribute ); } } $sister = new Sister( 5 ); $brother = new Brother( 5 ); assert( $sister == $brother ); // will FAIL! ?> This assertion will fail, because sister and brother are not of the same child class! If you want to compare based on the parent class object type only, you might have to define a function for comparisons like these, and use it instead of the == operator: <?php function SiblingsEqual( $a, $b ) { if ( !( $a instanceof Mom ) ) { return false; } if ( !( $b instanceof Mom ) ) { return false; } if ( $a->Attribute() != $b->Attribute() ) { return false; } return true; } assert( SiblingsEqual( $sister, $brother ) ); // will succeed ?> donny
In a reaction to Jony dos Santos Kostetzer. It does matter if they have different values. You're using the method Flag within the class Flag. This method returns the given parameter or, if no parameter is set, true. The comparison functions compares the 2 outcomes. In your example true and 10. In PHP this would be similar to : <?php if (true == 10) { return true ; } ?> Which would return true. So you could say that the values have the same outcome even though the input is visibly not the same. Another example : <?php /* ... */ $o = new Flag(1); $p = new Flag(10); /* ... */ echo "Two instances of the same class\n"; compareObjects($o, $p); ?> output: Two instances of the same class o1 == o2 : FALSE o1 != o2 : TRUE o1 === o2 : FALSE o1 !== o2 : TRUE as can be expected. rune
I haven't found a build-in function to check whether two obects are identical - that is, all their fields are identical. In other words, <? class A { var $x; function __construct($x) { $this->x = $x; } } $identical1 = new A(42); $identical2 = new A(42); $different = new A('42'); ?> Comparing the objects with "==" will claim that all three of them are equal. Comparing with "===" will claim that all are un-equal. I have found no build-in function to check that the two identicals are identical, but not identical to the different. The following function does that: <? function deepCompare($a,$b) { if(is_object($a) && is_object($b)) { if(get_class($a)!=get_class($b)) return false; foreach($a as $key => $val) { if(!deepCompare($val,$b->$key)) return false; } return true; } else if(is_array($a) && is_array($b)) { while(!is_null(key($a) && !is_null(key($b)))) { if (key($a)!==key($b) || !deepCompare(current($a),current($b))) return false; next($a); next($b); } return true; } else return $a===$b; } ?> 07-mar-2007 10:17
<? class _testCompare { public $num=4; } $o1=new _testCompare; $o2=new _testCompare; echo 'Both eq: ',($o1==$o2?'true':'false'),"\n<br />\n"; $o2->num=8; echo 'No eq: ',($o1==$o2?'true':'false'),"\n<br />\n"; $o2->num=4; echo 'Both eq: ',($o1==$o2?'true':'false'),"\n<br />\n"; $o2->num='4'; echo 'Both paraeq: ',($o1==$o2?'true':'false'),"\n<br />\n"; /* output: Both eq: true No eq: false Both eq: true Both paraeq: true */ ?> jony
"When using the comparison operator (==), object variables are compared in a simple manner, namely: Two object instances are equal if they have the same attributes and values, and are instances of the same class." Actually, it doesn't matter if they have different values: <?php /* ... */ $o = new Flag(); $p = new Flag(10); /* ... */ echo "Two instances of the same class\n"; compareObjects($o, $p); ?> output: Two instances of the same class o1 == o2 : TRUE o1 != o2 : FALSE o1 === o2 : FALSE o1 !== o2 : TRUE Jony dos Santos Kostetzer |
Change LanguageIntroduction The Basics Autoloading Objects Constructors and Destructors Visibility Scope Resolution Operator (::) Static Keyword Class Constants Class Abstraction Object Interfaces Overloading Object Iteration Patterns Magic Methods Final Keyword Object cloning Comparing objects Reflection Type Hinting Late Static Bindings |