Reputation: 31
I came with this idea because of the following problem:
Imagine that I have the following class:
Class Plane {
public $color;
public $metal;
public $motor;
}
Pretty simple, but imagine that is stored in db and have a model with this and bla bla bla, and user can update it. So when the user creates a new plane it will be:
new Plane("Yellow","Iron","2000cv");
And this is storage on database, and in this that database i have a log table to track who and when this was change, but today i dont have what was change so my question is, How i can take two instances of same class and in a function for example output the diferences of this classes?
The old plane is that:
new Plane("Yellow","Iron","2000cv");
And the new one is that:
new Plane("Blue","Chrome","2000cv");
And some function that recieves both instances and output that:
Array(
'color'=>Array(
'old'=>'Yellow',
'new'=>'Blue'
),
'metal'=>Array(
'old'=>'Iron',
'new'=>'Chrome'
)
)
I know how to do it with ifs and wherever but i don't know if is the best approach.
Upvotes: 1
Views: 90
Reputation: 10202
If I understand it correctly you store two objects in the database and want to compare them. Right?
Suppose you have these two objects;
$plane_one = new Plane ( 'Yellow', 'Iron', '2000cv' );
$plane_two = new Plane ( 'Blue', 'Chrome', '2000cv' );
This one is actually not adviseable, as the code isn't maintainable, but hey, it works.
function comparePlanes ( &obj1, &$obj2 ) {
$differences = array ();
if ( $obj1->color != $obj2->color ) {
$differences['color'] => array($obj1->color, $obj2->color);
}
if ( $obj1->metal != $obj2->metal ) {
$differences['metal'] => array($obj1->metal, $obj2->metal);
}
if ( $obj1->motor != $obj2->motor ) {
$differences['motor'] => array($obj1->motor, $obj2->motor);
}
return $differences;
}
This would return;
Array (
'color' => Array('Yellow', 'Blue'),
'metal' => Array('Iron', 'Chrome')
)
More fun would it be when your function would just spit out all differences between all properties, while being agnostic to which properties there are. For this we can use the ReflectionClass
.
function compareObjects( &$obj1, &$obj2 ) {
if ( ! is_object($obj1) || ! is_object($obj2) || get_class($obj1) != get_class($obj2) ) {
return array(); // One of them isn't an object, or they are not from the same class
}
$reflection = new ReflectionClass(get_class($obj1));
$properties = $reflection->getProperties();
$differences = array();
foreach( $properties as $property ) {
if ( $obj1->{$property->name} != $obj2->{$property->name} ) {
$differences[$property->name] = array($obj1->{$property->name}, $obj2->{$property->name});
}
}
return $differences;
}
Now this would output the exact same. But if you would now alter your class to hold the number of passengers for example;
class Plane {
...
public $passengers;
...
function __construct($color, $metal, $motor, $passengers) {
...
$this->passengers = $passengers;
}
}
And you would input these two objects;
$plane_one = new Plane ( 'Yellow', 'Iron', '2000cv', 12 );
$plane_two = new Plane ( 'Blue', 'Chrome', '2000cv', 6 );
You would get the differences as well;
Array (
[color] => Array ( 'Yellow', 'Blue' ),
[metal] => Array ( 'Iron', 'Chrome' ),
[passengers] => Array ( 12, 6 )
)
You can even pass any other pair of objects if you want to. Doesn't matter
Upvotes: 3