Last active
July 24, 2020 10:56
-
-
Save yoander/a0b00db96eddb68a41fab182c74ed460 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Comparator; | |
use ReflectionObject; | |
use InvalidArgumentException; | |
class ObjectComparator | |
{ | |
/** | |
* Compare 2 objects | |
* | |
* @param $o1 | |
* @param $o2 | |
* @param $strict Compare in simple (==) or in strict way (===) | |
* @return true objects are equals, false objects are differents | |
*/ | |
public static function equal($o1, $o2, $strict = false) | |
{ | |
return $strict ? $o1 === $o2 : $o1 == $o2; | |
} | |
/** | |
* Find the differences between 2 objects using Reflection. | |
* | |
* @param $o1 | |
* @param $o2 | |
* @return array Properties that have changed | |
* @throws InvalidArgumentException | |
*/ | |
public static function diff($o1, $o2) | |
{ | |
if (!is_object($o1) || !is_object($o2)) { | |
throw new InvalidArgumentException("Parameters should be of object type!"); | |
} | |
$diff = []; | |
if (get_class($o1) == get_class($o2)) { | |
$o1Properties = (new ReflectionObject($o1))->getProperties(); | |
$o2Reflected = new ReflectionObject($o2); | |
foreach ($o1Properties as $o1Property) { | |
$o2Property = $o2Reflected->getProperty($o1Property->getName()); | |
// Mark private properties as accessible only for reflected class | |
$o1Property->setAccessible(true); | |
$o2Property->setAccessible(true); | |
if (($oldValue = $o1Property->getValue($o1)) != ($newValue = $o2Property->getValue($o2))) { | |
$diff[$o1Property->getName()] = [ | |
'old_value' => $oldValue, | |
'new_value' => $newValue | |
]; | |
} | |
} | |
} | |
return $diff; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
include __DIR__ . '/ObjectComparator.php'; | |
use Comparator\ObjectComparator as Comparator; | |
class Person | |
{ | |
public $name = ''; | |
private $age = 0; | |
public function setAge($age) | |
{ | |
$this->age = $age; | |
} | |
} | |
function print_ln() { | |
return php_sapi_name() == 'cli' ? PHP_EOL : nl2br(PHP_EOL); | |
} | |
$p1 = new Person(); | |
$p2 = new Person(); | |
echo '1. p1 == p2 => ', Comparator::equal($p1, $p2) ? 'Yes' : 'No', print_ln(); // Print Yes | |
$p1->name = 'Juan'; | |
echo '2. p1 == p2 => ', Comparator::equal($p1, $p2) ? 'Yes' : 'No', print_ln(); // Print No | |
$p2->name = 'Juan'; | |
echo '3. p1 == p2 => ', Comparator::equal($p1, $p2) ? 'Yes' : 'No', print_ln(); // Print Yes | |
$p2->setAge(20); | |
echo '4. p1 == p2 => ', Comparator::equal($p1, $p2) ? 'Yes' : 'No', print_ln(); // Print No | |
$p1->setAge(20); | |
echo '5. p1 == p2 => ', Comparator::equal($p1, $p2) ? 'Yes' : 'No', print_ln(); // Print Yes | |
$p2 = clone $p1; | |
echo '6. p1 == p2 => ', Comparator::equal($p1, $p2, true) ? 'Yes' : 'No', print_ln(); // Print No | |
$p2 = $p1; | |
echo '7. p1 == p2 => ', Comparator::equal($p1, $p2, true) ? 'Yes' : 'No', print_ln(); // Print Yes | |
$p3 = new Person(); | |
$p3->name = 'Pepe'; | |
$p3->setAge(50); | |
echo '8. Get the differences for p1, p3', print_ln(); | |
foreach (Comparator::diff($p1, $p3) as $property => $diff) { | |
echo $property, ' => ', 'old value: ', $diff['old_value'], ', new value: ', $diff['new_value'], print_ln(); | |
} | |
// Get the differences for p1, p3 | |
// name => old value: Juan, new value: Pepe | |
// age => old value: 20, new value: 50 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment