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

search for in the

Reflection> <Клонирование объектов
Last updated: Fri, 05 Sep 2008

view this page in

Сравнение объектов

В PHP 5 сравнение объектов является более сложным процессом, чем в PHP 4, а также процессом, более соответствующим идеологии объектно-ориентированного языка (здесь не имеется в виду, что PHP 5 является таковым).

При использовании оператора сравнения (==), свойства объектов просто сравниваются друг с другом, а именно: два объекта равны, если они содержат одинаковые свойства и одинаковые их значения и являются экземплярами одного и того же класса.

С другой стороны, при использовании оператора идентичности (===), свойства объекта считаются идентичными тогда и только тогда, когда они ссылаются на один и тот же экземпляр одного и того же класса.

Следующий пример внесёт ясность.

Пример #1 Пример сравнения объектов в PHP 5

<?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 
OtherFlag {
    var 
$flag;

    function 
OtherFlag($flag=true) {
            
$this->flag $flag;
    }
}

$o = new Flag();
$p = new Flag();
$q $o;
$r = new OtherFlag();

echo 
"Два экземпляра одного и того же класса\n";
compareObjects($o$p);

echo 
"\nДве ссылки на один и тот же экземпляр\n";
compareObjects($o$q);

echo 
"\nЭкземпляры двух разных классов\n";
compareObjects($o$r);
?>
Результатом выполнения этого кода будет:
Два экземпляра одного и того же класса
o1 == o2 : TRUE
o1 != o2 : FALSE
o1 === o2 : FALSE
o1 !== o2 : TRUE

Две ссылки на один и тот же экземпляр
o1 == o2 : TRUE
o1 != o2 : FALSE
o1 === o2 : TRUE
o1 !== o2 : FALSE

Экземпляры двух разных классов
o1 == o2 : FALSE
o1 != o2 : TRUE
o1 === o2 : FALSE
o1 !== o2 : TRUE
    



Reflection> <Клонирование объектов
Last updated: Fri, 05 Sep 2008
 
add a note add a note User Contributed Notes
Сравнение объектов
cross+php at distal dot com
05-Mar-2008 04:50
In response to "rune at zedeler dot dk"s comment about class contents being equal, I have a similar issue.  I want to sort an array of objects using sort().

I know I can do it with usort(), but I'm used to C++ where you can define operators that allow comparison.  I see in the zend source code that it calls a compare_objects function, but I don't see any way to implement that function for an object.  Would it have to be an extension to provide that interface?

If so, I'd like to suggest that you allow equivalence and/or comparison operations to be defined in a class definition in PHP.  Then, the sorts of things rune and I want to do would be much easier.
dionyziz at deviantart dot com
11-Mar-2007 03:20
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
?>
rune at zedeler dot dk
28-Feb-2007 04:34
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;
}
?>
rune at zedeler dot dk
28-Feb-2007 04:27
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;
}
?>
jazfresh at hotmail.com
08-Dec-2006 10:36
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

Reflection> <Клонирование объектов
Last updated: Fri, 05 Sep 2008
 
 
show source | credits | sitemap | contact | advertising | mirror sites