ArrayObject Vergleich

Erst gestern bin ich bei der Überarbeitung einer Applikation für die vs vergleichen-und-sparen GmbH auf ein Problem beim Vergleich zweier Arrays des Typs ArrayObject gestoßen. Zwar beschreibt das PHP Manual den Vergleich von Objekten ziemlich genau. Nur wollte es eben mit dem ArrayObject nicht recht klappen. Zunächst aber erstmal ein bisschen Code, so dass das Problem nachvollziehbar ist.

// Unser erstes ArrayObject
$oArr1 = new ArrayObject(
    array('bla' => 'blubb'),
    ArrayObject::ARRAY_AS_PROPS
);

// Unser zweites ArrayObject - identisch mit $oArr1
$oArr2 = new ArrayObject(
    array('bla' => 'blubb'),
    ArrayObject::ARRAY_AS_PROPS
);

// Unser drittes ArrayObject - nicht identisch mit $oArr1
$oArr3 = new ArrayObject(
    array('bla' => 'bar'),
    ArrayObject::ARRAY_AS_PROPS
);

// Erster Vergleich - erwartetes Ergebnis: true
var_dump($oArr1 == $oArr2);

// Zweiter Vergleich - erwartetes Ergebnis: false
var_dump($oArr1 == $oArr3);

Im Beispiel werden zunächst drei ArrayObject Instanzen erstellt. Während die erste und zweite Instanz identisch sind, unterscheidet sich die dritte Instanz, weil hier ein anderes Array vorliegt. So erklärt sich dann auch der durchgeführte Vergleich. Im ersten Vergleich werden die erste und die zweite Instanz miteinander verglichen. Da beide absolut identisch sind, erwarten wir hier logischerweise ein true. Im zweiten Vergleich werden die erste und die dritte Instanz miteinander verglichen. Da sich beide Instanzen voneinander unterscheiden, erwarten wir hier dann auch ein false.

Pustekuchen! Während in meiner lokalen Entwicklungsumgebung die erwarteten Ergebnisse erzielt wurden, erhielt ich auf dem Server immer true. Was war da los? Während ich in meiner lokalen Entwicklungsumgebung PHP 5.4.7 verwende, läuft auf dem Server eine zwar stabile, aber stark veraltete PHP Version 5.2.0. Für diese Version liegt ein Bug für den Vergleich von Instanzen des ArrayObject vor, der erst ab der Version 5.3.11 gefixt ist.

Was also tun? In der Bugbeschreibung findet man einen Lösungsansatz mit der ArrayObject::getArrayCopy() Methode, der dazu führt, dass der Vergleich die richtigen Ergebnisse liefert. Ich habe mich auf die Schnelle für folgenden Ansatz entschieden.

// Erwartetes Ergebnis: false
var_dump(count(array_diff((array) $oArr1, (array) $oArr3)) == 0);

Haben wir wieder was gelernt. 😉

Kommentar verfassen

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.