Сравните объекты на равенство в Stack Overflow

конкретика

Во-первых, определение «равенство» в моем случае состоит в том, что объекты равны, когда они имеют одинаковую структуру и значения для этой структуры. Тем не менее, они могут не совпадать, или свойства могут быть не в том же «порядке» (я имею в виду, как они были назначены / определены). Есть такие вопросы здесь на SO, как этот — но они не покрывают мое дело.

Мне нужно сравнивать сущности в PHP из-за тестирования моих целей кода — и эти сущности могут быть чем угодно. В частности, они могут быть объектами. Сравнение объектов, однако, это не «безопасно». Представьте, что вы сравниваете:

$result = $objectX == $objectY;

И это может привести к фатальной ошибке в случае, когда объекты имеют циклические ссылки. Простой пример для этого я подготовил Вот. Как мы видим, PHP пытается следовать за вложенными уровнями и терпит неудачу в бесконечном цикле — потому что по своей природе объекты одинаковы по содержанию, но имеют циклические ссылки.

Важной деталью является то, что объекты могут содержать несериализуемые элементы (например, замыкания), что делает невозможным использование подхода «seralize / unserialize» (даже если забыть о неупорядоченном сравнении)

Текущий подход

У меня есть код как этот (слишком много, чтобы вставить здесь, но на всякий случай, вот суть) — так я выступаю ДФС там и ловятся ситуации с такими циркулярными ссылками. Как видите, это довольно сложно — и, кстати, это медленно.

Другая проблема, связанная с текущим подходом, заключается в том, что при наличии массивов внутри объектов они будут сравниваться с учетом порядка элементов, что в некоторых случаях мне не подходит (в идеале — когда я смогу изменить порядок). мудрое сравнение), но чтобы преодолеть его изначально, мне, вероятно, понадобится как-то «отсортировать» массивы — и я понятия не имею, как это сделать — поскольку, опять же, сравнение этих элементов массивов не будет безопасным.

Более того, ссылки на циклические массивы также будут вызывать сбой:

$array = ['foo', $object, &$array];

Вопрос

Какие могут быть другие (лучшие) подходы к решению вопроса? Сериализация объектов могла бы иметь место, но из-за неупорядоченного набора свойств это потерпит неудачу для меня.

11

Решение

Знаете ли вы Doctrine \ Common \ Util \ Debug :: export ($ class, $ maxDepth)?

Этот метод «export» предотвращает вас от бесконечного цикла и возвращает массив, который можно использовать для создания diff.

За определенной глубиной нет необходимости идти дальше и
с $ maxDepth вы можете указать «точность» вашего сравнения.

1

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

Других решений пока нет …

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