I need to check if two PHP object are equal in terms of equal values. Of course I could easily add an isEqualTo(...)
method to the class that compares all relevant values. However the concrete class will change in the near future and I would like to know if there is any automated way to do this.
Example:
class Contact {
private name; // String
private phone; // Int
private someObject; // Custom Object
public function getName() {
return $this->name;
}
public function setName($newName) {
$this->name = $newName;
}
public function getPhone() {
return $this->phone;
}
public function setPhone($newPhone) {
$this->phone = $newPhone;
}
public function getSomeObject() {
return $this->someObject;
}
public function setSomeObject($newObj) {
$this->someObject = $newObj;
}
// Manual Solution
public function isEqualTo($contact) {
result = $this->name == $contact->getName();
result &= $this->phone == $contact->getPhone();
result &= $this->someObject == $contact->getSomeObject();
return result;
}
}
This would obviously work. Of course I am aware of the the limitation of comparing someObject
(need to be the exact some object to be true) but this is OK.
However the class Contact
will be extended in the near future. Everytime I add new properties/values to the class I have to add them to isEqualTo
as well. No big deal but a little bit cumbersome.
So, is there any way to implement isEqualTo
to automatically all available public properties?
I found get_class_vars
and get_object_vars
but these methodes will not work with getters and setters but only with vars that can be accessed directly.
I found get_class_methodes
but this return all methodes and not only getters and setters. Filtering the methodes names by get...
and set...
would work of course, but this would be more like a hack than a "nice and clean" soltution.
In short: Is there any "correct" way to automatically check two PHP object for equality?
I wouldn't go so far as to say that this is the "correct" way, but since you don't want to implement/maintain your own comparison function/method you might be interested in php's default behaviour including the comparison of protected/private properties:
<?php
class Foo {
private $x,$y,$z;
public function __construct($x,$y,$z) {
$this->x = $x;
$this->y = $y;
$this->z = $z;
}
}
$f1 = new Foo(1,2,3);
$f2 = new Foo(4,5,6);
$f3 = new Foo(1,2,3);
var_dump(
$f1==$f2,
$f1==$f3
);
prints
bool(false)
bool(true)
which might or might not be sufficient for you.
As pointed out by Alma Do, circular references like e.g.
<?php
class Foo {
private $x,$y,$z;
public function __construct($x,$y,$z) {
$this->x = $x;
$this->y = $y;
$this->z = $z;
}
public function setZ($z) {
$this->z = $z;
}
}
$f1 = new Foo(1,2,3);
$f2 = new Foo(4,5,6);
$f3 = new Foo(1,2,3);
$f1->setZ($f3);
$f3->setZ($f1);
var_dump(
$f1==$f2,
$f1==$f3
);
will cause a Fatal error: Nesting level too deep - recursive dependency?
.