That’s tricky! Let’s assume we have two arrays like these:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
class Foo { public $bar; public $flag; public function __construct(string $bar, bool $flag) { $this->bar = $bar; $this->flag = $flag; } public function __toString(): string { return $this->bar; } } $array1 = [ new Foo('test', true), ]; $array2 = [ new Foo('test', false), ]; |
Looking at these few lines I would expect that those two arrays are different but if we compare them with php array_diff function they’re the same:
1 2 3 4 |
var_dump(array_diff($array1, $array2)); array(0) { } |
This happens because array_diff compares array elements as string so it calls the __toString method implicity and the string rappresentation of those objects is the same.
When you need to compare two arrays of objects is better to use array_udiff function which let you define a custom function to perform the difference.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
var_dump(array_udiff($array1, $array2, function ($a, $b) { $barCmp = strcmp($a->bar, $b->bar) === 0; $flagCmp = $a->flag === $b->flag; return $barCmp && $flagCmp ? 0 : 1; })); array(1) { [0]=> object(Foo)#1 (2) { ["bar"]=> string(4) "test" ["flag"]=> bool(true) } } |
I hope I spared you some minutes and a little headache.