suche nach in der

Type Hinting> <Objekte klonen
Last updated: Sat, 07 Jan 2012

view this page in

Objekte vergleichen

In PHP 5 ist der Vergleich von Objekten komplizierter als in PHP 4 und in stärkerer Übereinstimmung zu dem, was man von einer objektorientierten Programmiersprache erwartet (nicht dass PHP 5 eine derartige Sprache wäre).

Wenn man den Vergleichsoperator (==) benutzt, werden Objektvariablen auf einfache Weise verglichen, d.h.: Zwei Objektinstanzen sind gleich, wenn sie die gleichen Attribute haben und Instanzen der selben Klasse sind.

Wenn man andererseits den Identitätsoperator benutzt (===), sind zwei Objekte identisch, genau dann, wenn sie die selbe Instanz der selben Klasse referenzieren.

Ein Beispiel wird diese Regeln verdeutlichen.

Beispiel #1 Beispiel für Objektvergleiche in 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
{
    public 
$flag;

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

class 
OtherFlag
{
    public 
$flag;

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

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

echo 
"Zwei Instanzen der selben Klasse\n";
compareObjects($o$p);

echo 
"\nZwei Referenzen auf die selbe Instanz\n";
compareObjects($o$q);

echo 
"\nInstanzen zweier verschiedener Klassen\n";
compareObjects($o$r);
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

Zwei Instanzen der selben Klasse
o1 == o2 : TRUE
o1 != o2 : FALSE
o1 === o2 : FALSE
o1 !== o2 : TRUE

Zwei Referenzen auf die selbe Instanz
o1 == o2 : TRUE
o1 != o2 : FALSE
o1 === o2 : TRUE
o1 !== o2 : FALSE

Instanzen zweier verschiedener Klassen
o1 == o2 : FALSE
o1 != o2 : TRUE
o1 === o2 : FALSE
o1 !== o2 : TRUE

Hinweis:

Erweiterungen können eigenen Regeln für ihre Objektvergleiche definieren.



add a note add a note User Contributed Notes
Objekte vergleichen
dionyziz at deviantart dot com
11-Mar-2007 04: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
?>
07-Mar-2007 11: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

*/
?>
rune at zedeler dot dk
28-Feb-2007 05: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 05: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 11: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
donny at semeleer dot nl
14-Sep-2006 10:56
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.
jony AT jonysk DOT net
27-Aug-2006 08:23
"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

Type Hinting> <Objekte klonen
Last updated: Sat, 07 Jan 2012