-1

I have to arrays and want to check if they have the same values, not matters the order, so I used == operator:

$roles = ['admin', 'manager'];
$needle = ['manager', 'admin'];

$needle == $roles; // false

The problem is that with same values but in different order, the operator evaluates the comparison to false.

How to properly compare two arrays to check if values are the same?

UPDATE

For now, I'm going with array_intersect:

$hasExactRoles = (
  (array_intersect($roles, $needle) === $roles) &&
  (array_intersect($needle, $roles) === $needle)
);
Alexandre Thebaldi
  • 4,546
  • 6
  • 41
  • 55
  • Take a look at the [documentation](http://php.net/manual/en/language.operators.array.php). `$a == $b` if `$a` and `$b` have the same key/value pairs. – axiac Jan 17 '18 at 11:49
  • Read this pre-existing page: https://stackoverflow.com/questions/5678959/php-check-if-two-arrays-are-equal It covers everything. – mickmackusa Jan 17 '18 at 11:57
  • Does this answer your question? [PHP - Check if two arrays are equal](https://stackoverflow.com/questions/5678959/php-check-if-two-arrays-are-equal) – tanaydin Jul 31 '20 at 14:49

3 Answers3

4

You can check what is a difference between arrays.

$roles = ['admin', 'manager'];
$needle = ['manager', 'admin'];

if (empty(array_diff($roles, $needle))) {
    echo 'The same.';
}


The correct answer is:

$roles = ['admin', 'manager'];
$needle = ['manager', 'admin'];

sort($roles);
sort($needle);

if ($roles === $needle) {
    echo 'The same.';
}
Michał Szczech
  • 466
  • 4
  • 17
2

== with arrays evaluates to true if $a and $b have the same key/value pairs. In your example, the numeric keys 0 and 1 match up with different values, so the comparison fails.

As other people have mentioned, you can use array_diff to compare just the values, e.g.

if (count(array_diff($needle, $roles)) > 0) {
  // Arrays are not identical
}

but note that array_diff only works in one direction - it returns the values from the first argument that are not present in the second, so you might also need to run it with the arguments in reverse order, depending on your exact scenario.

As @axiac mentions in the comment, this still won't cover situations where elements can occur multiple times. If this applies then there are probably better ways that you can approach this, e.g. by sorting the arrays or making use of functions like array_intersect.

iainn
  • 16,826
  • 9
  • 33
  • 40
  • 1
    Even if one uses `array_diff()` in both directions, the arrays might still be different if some of their values appear more than once in one of the arrays. However, this is the most detailed answer until now. – axiac Jan 17 '18 at 11:51
  • Maybe `(array_intersect($needle, $roles) === $needle && array_intersect($roles, $needle) === $roles)` would be the best choice for this case. – Alexandre Thebaldi Jan 17 '18 at 12:00
  • @AlexandreThebaldi I'm not sure the order of the elements returned from `array_intersect` is guaranteed, so that might still end up with issues. The best choice will depend on *why* you want to compare them - if you want to check that every `$needle` is present in `$roles`, then a one-way diff is perfect. If you want an exact match, including situations where elements can be duplicated in either of the arrays, then it'll become more complicated. – iainn Jan 17 '18 at 12:15
  • @iainn My case doesn't deals with duplicated elements (cause of database constraints, FYI). It's just a check if `$roles` have exactly the same values of `$needle`. This will be used in a controller layer to authorize users to access contents by their exact roles. – Alexandre Thebaldi Jan 17 '18 at 12:23
-2

Use the array_diff function to return any values from the second array that are not in the first. If array_diff is empty then the arrays are the same:

$roles = ['admin', 'manager'];
$needle = ['manager', 'admin'];
$result = array_diff($roles, $needle);
if (empty($result)) {
    // Arrays are the same
}
davidethell
  • 11,708
  • 6
  • 43
  • 63