Автопроверка равенства двух объектов?

Мне нужно проверить, равны ли два объекта PHP с точки зрения равных значений. Конечно, я мог бы легко добавить isEqualTo(...) метод класса, который сравнивает все соответствующие значения. Однако конкретный класс изменится в ближайшем будущем, и я хотел бы знать, есть ли какой-нибудь автоматизированный способ сделать это.

Пример:

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;
}
}

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

Однако класс Contact будет продлен в ближайшее время. Каждый раз, когда я добавляю новые свойства / значения в класс, я должен добавить их в isEqualTo также. Ничего страшного, но немного громоздко.

Итак, есть ли способ реализовать isEqualTo автоматически все доступные публичные свойства?

я нашел get_class_vars а также get_object_vars но эти методы не будут работать с геттерами и сеттерами, а только с переменными, к которым можно получить прямой доступ.

я нашел get_class_methodes но это возвращает все методы, а не только геттеры и сеттеры. Фильтрация имен методов по get... а также set... будет работать, конечно, но это будет больше похоже на взлом, чем «хороший и чистый» раствор.

Короче: Есть ли «правильный» способ автоматически проверить два объекта PHP на равенство?

4

Решение

Я бы не сказал, что это «правильный» путь, но, поскольку вы не хотите реализовывать / поддерживать свою собственную функцию / метод сравнения, вас может заинтересовать поведение по умолчанию в php, включая сравнение protected / частные свойства:

<?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
);

печать

bool(false)
bool(true)

что может или не может быть достаточно для вас.


Как указал Альма До, циклические ссылки, такие как, например,

<?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
);

вызовет Fatal error: Nesting level too deep - recursive dependency?,

4

Другие решения

Вы можете использовать Reflection, но я не думаю, что это хорошая идея. Может быть, serialize () — лучшее решение?

function isEquals(self $obj){
return serialize($obj)===serialize($this)
}
0

По вопросам рекламы [email protected]