Предположим, у меня есть объект – объект User в этом случае – и я хотел бы отслеживать изменения с помощью отдельного класса. Пользовательский объект не должен каким-либо образом изменять его поведение, чтобы это произошло.
Поэтому мой отдельный класс создает «чистую» копию, сохраняет его где-то локально, а затем может сравнивать объект User с исходной версией, чтобы увидеть, что-либо изменилось в течение его срока службы.
Есть ли функция, шаблон или что-нибудь, что может быстро сравнить две версии объекта User?
Вариант 1 Может быть, я мог бы сериализовать каждую версию и напрямую сравнить или хешировать их и сравнить?
Вариант 2 Возможно, мне нужно просто создать ReflectionClass, выполнить все свойства этого класса и посмотреть, имеют ли две версии те же значения свойств?
Вариант 3 Возможно, существует простая нативная функция, такая как objects_are_equal($object1,$object2);
?
Какой самый быстрый способ сделать это?
Единственный способ доступа ко всем (общедоступным, защищенным и приватным) свойствам объекта без его модификации – это отражение . Вы могли бы, если бы захотели, клонировать объект до его модификации, а затем сравнивать их, используя функции отражения, чтобы перебирать различные свойства одного из двух объектов и сравнивать значения. Это эффективно скажет вам, какие свойства изменились.
Если все, что вам нужно посмотреть, это изменение или изменение объектов, вы можете использовать операторы == или ===. Посмотрите на раздел сравнения объектов документации PHP.
Тем не менее, было бы проще просто отслеживать, что вы изменили, когда вы меняете их?
Существует целый сайт на php.net, который занимается только сравнением объектов:
http://php.net/manual/en/language.oop5.object-comparison.php
Также хорошо читайте:
http://www.tuxradar.com/practicalphp/6/12/0
Я бы сказал, что вы должны использовать метод «clone» при копировании вашего объекта, а затем сравнить его, как сказано в статье php.net.
Также быстрым способом было бы объявить статический метод в классе, который просто сравнивает соответствующие «свойства», например, «имя пользователя», «пароль», «cookie», …
class User { public $username; public $password; public $cookie; # other code public static function compare(&$obj1, &$obj2) { if ($obj1->username != $obj2->username) return 0 if ($obj1->password != $obj2->password) return 0 if ($obj1->cookie != $obj2->cookie) return 0 return 1 } };
Вот фрагмент кода, который поддерживает частные свойства:
$reflection_1 = new \ReflectionClass($object_1); $reflection_2 = new \ReflectionClass($object_2); $props_1 = $reflection_1->getProperties(); foreach ($props_1 as $prop_1) { $prop_1->setAccessible(true); $value_1 = $prop_1->getValue($object_1); $prop_2 = $reflection_2->getProperty($prop_1->getName()); $prop_2->setAccessible(true); $value_2 = $prop_2->getValue($object_2); if ($value_1 === $value_2) { // ... } else { // ... } }
Обратите внимание, что если $object_1
имеет свойства, $object_2
нет у объекта $object_2
, то при попытке доступа к ним приведенный выше код приведет к ошибкам.
Для такого случая вам нужно сначала пересечь $reflection_1->getProperties()
с помощью $reflection_2->getProperties()
.