317

I'd like to check if two arrays are equal. I mean: same size, same index, same values. How can I do that?

Using !== as suggested by a user, I expect that the following would print enter if at least one element in the array(s) are different, but in fact it does not.

if (($_POST['atlOriginal'] !== $oldAtlPosition) 
    or ($_POST['atl'] !== $aext) 
    or ($_POST['sidesOriginal'] !== $oldSidePosition) 
    or ($_POST['sidesOriginal'] !== $sideext)) {

    echo "enter";
}
izeke
  • 63
  • 8
markzzz
  • 44,504
  • 107
  • 265
  • 458

16 Answers16

585
$arraysAreEqual = ($a == $b); // TRUE if $a and $b have the same key/value pairs.
$arraysAreEqual = ($a === $b); // TRUE if $a and $b have the same key/value pairs in the same order and of the same types.

See Array Operators.

EDIT

The inequality operator is != while the non-identity operator is !== to match the equality operator == and the identity operator ===.

Stefan Gehrig
  • 78,962
  • 24
  • 149
  • 181
  • 91
    A side note: This approach **works** for multidimensional arrays as well (it wasn't that obvious for me before). – trejder Sep 23 '13 at 08:41
  • **Not works** when indexes not same... Example: my dump of {1,2,5} is `array(3) { [0]=>int(1) [1]=>int(2) [4]=>int(5) }` (indexes 0,1,4), but another arrays use indexes that are the expected (0,1,2). It is a PHP bug? – Peter Krauss Oct 13 '14 at 19:22
  • 5
    PS: solution is to use `array_values($a)==array_values($b)`... Another usual problem is about unique values, so remember that exist `array_unique()`. – Peter Krauss Oct 15 '14 at 10:53
  • 1
    Saying == checks for matching key/value pairs is a little misleading. It appears to actually check the values == each other. So you might be surprised to find that array(0) == array('not zero') is true. – Andrew Jul 31 '15 at 16:59
  • 19
    This answer is wrong. `==` works regardless of order only for typical dictionaries like `[1 => 'a', 2 => 'b']`. For e.g. `[1 => 'a', 2 => 'b'] == [2 => 'b', 1 => 'a']`. For indexed arrays like `['a', 'b']` `==` doesn't work as stated. For e.g. `['a', 'b'] != ['b', 'a']`. – nawfal Nov 15 '15 at 12:56
  • 46
    @nawfal: Your assumption is wrong. `['a', 'b']` is an array `[0 => 'a', 1 => 'b']`, while `['b', 'a']` is an array `[0 => 'b', 1 => 'a']`. That's why they don't have the same key/value pairs as stated in my answer and that's why `==` does not work between those. – Stefan Gehrig Nov 15 '15 at 13:00
  • 35
    @StefanGehrig oh you're right. I will leave my comment as such to make my foolishness evident :) – nawfal Nov 15 '15 at 13:03
  • 1
    +1 for `same order`. And it works with `===` even if keys in one array are numeric bounded by quotes. (e.g. '0', '1'). – shyammakwana.me May 04 '16 at 14:11
  • 1
    Note that `===` only requires values to have the same types and doesn't require keys, which means `([0 => 'a', 1 => 'b'] === [false => 'a', '1' => 'b']) === true`. – samluthebrave Jan 22 '17 at 02:02
  • 1
    http://stackoverflow.com/questions/21138505/check-if-two-arrays-have-the-same-values is the best way – Aaska Patel Feb 21 '17 at 10:32
  • 1
    can anyone link to an explanation as to why === is faster in large arrays than == (100k character arrays) – HaydenKai Jun 06 '17 at 05:45
  • 1
    [1,2] === [2,1] returns false – holden321 Aug 14 '18 at 06:46
  • 1
    @holden321. That's because `[1,2] === [2,1]` *is* false. See Stefan Gehrig's explanation above. `[1, 2]` is shorthand notation for `[0 => 1, 1 => 2]`, while `[2, 1]` is short for `[0 => 2, 1 => 1]`, so the two arrays *are* different, as keys and values don't match. – TRiG Oct 22 '19 at 09:44
  • 1
    Note that if you are importing CSV for example or from text files, this will probably do not work. Doing a var_dump you can notice that depending on the encoding of the file, an id that is supposely string(2) will come as string(5) so this comparation will fail. Even != will fail even with the claim that does not check types (at least does for me) – Martin Fasani Feb 14 '20 at 09:36
102

According to this page.

NOTE: The accepted answer works for associative arrays, but it will not work as expected with indexed arrays (explained below). If you want to compare either of them, then use this solution. Also, this function may not works with multidimensional arrays (due to the nature of array_diff function).

Testing two indexed arrays, which elements are in different order, using $a == $b or $a === $b fails, for example:

<?php
    (array("x","y") == array("y","x")) === false;
?>

That is because the above means:

array(0 => "x", 1 => "y") vs. array(0 => "y", 1 => "x").

To solve that issue, use:

<?php
function array_equal($a, $b) {
    return (
         is_array($a) 
         && is_array($b) 
         && count($a) == count($b) 
         && array_diff($a, $b) === array_diff($b, $a)
    );
}
?>

Comparing array sizes was added (suggested by super_ton) as it may improve speed.

Ivan
  • 11,733
  • 5
  • 35
  • 63
lepe
  • 22,543
  • 9
  • 85
  • 99
  • 3
    Attention: does not work as expected with [multidimensional arrays](http://stackoverflow.com/questions/19830585/why-array-diff-gives-array-to-string-conversion-error) – maersu Apr 09 '14 at 16:13
  • 9
    The above comment is false. If $b has all the elements $a has plus some extra ones, the two arrays are not equal yet the above code will say they are. – Ghola Sep 08 '14 at 12:14
  • 2
    might be worth adding count($a) == count($b) too – stefan Sep 07 '16 at 10:20
  • 2
    @super_ton: yes, before calling `array_diff` could speed-up the comparison. I will add it. Thanks – lepe Sep 08 '16 at 00:35
  • 1
    since **count($a) == count($b)**, another speed up is: `function array_equal($a, $b) { return ( is_array($a) && is_array($b) && count($a) == count($b) && !array_diff($a, $b) ); }` – Luca Manzo May 12 '17 at 07:57
  • 6
    Unfortunately, it does not work in some cases, for example, I've tested with the following case `$a = [1, 2, 2]; $b = [2, 1, 1];` and it returned `true`, but the two arrays are obviously not the same. – AwesomeGuy Sep 28 '18 at 13:00
  • if $a and $b have the same elements, both array_diff(a,b) and array_diff(b,a) are empty, the comparison between them doesn't make sense. – Pablo Pazos Oct 20 '20 at 21:48
36

Try serialize. This will check nested subarrays as well.

$foo =serialize($array_foo);
$bar =serialize($array_bar);
if ($foo == $bar) echo "Foo and bar are equal";
Iggi
  • 369
  • 3
  • 2
  • 7
    Problematic if the keys and values are shifted around just like using comparison. However, assuming they are expected to be 100% the same, this is the cleanest and easiest way to check deep equality! – Kevin Peno Aug 21 '13 at 20:59
  • 1
    I guess this is the best solution! It can compare multidimensional and associative arrays if they were previously sorted! – Rafael Moni Jul 24 '14 at 14:41
  • if the array is considered a SET, this doesn't work: it should be sorted on all nested levels to be able to check if the same items are included in any order. – Pablo Pazos Oct 20 '20 at 22:21
20

Short solution that works even with arrays which keys are given in different order:

public static function arrays_are_equal($array1, $array2)
{
    array_multisort($array1);
    array_multisort($array2);
    return ( serialize($array1) === serialize($array2) );
}
Samuel Vicent
  • 753
  • 6
  • 12
11

Compare them as other values:

if($array_a == $array_b) {
  //they are the same
}

You can read about all array operators here: http://php.net/manual/en/language.operators.array.php Note for example that === also checks that the types and order of the elements in the arrays are the same.

Emil Vikström
  • 84,510
  • 15
  • 132
  • 168
9

!=== will not work because it's a syntax error. The correct way is !== (not three "equal to" symbols)

Thom Smith
  • 13,160
  • 2
  • 40
  • 78
Sodhi saab
  • 2,238
  • 1
  • 16
  • 30
7
if (array_diff($a,$b) == array_diff($b,$a)) {
  // Equals
}

if (array_diff($a,$b) != array_diff($b,$a)) {
  // Not Equals
}

From my pov it's better to use array_diff than array_intersect because with checks of this nature the differences returned commonly are less than the similarities, this way the bool conversion is less memory hungry.

Edit Note that this solution is for plain arrays and complements the == and === one posted above that is only valid for dictionaries.

5
function compareIsEqualArray(array $array1,array $array):bool
{

   return (array_diff($array1,$array2)==[] && array_diff($array2,$array1)==[]);

}
dılo sürücü
  • 1,989
  • 1
  • 12
  • 19
3

Another method for checking equality regardless of value order works by using http://php.net/manual/en/function.array-intersect.php, like so:

$array1 = array(2,5,3);
$array2 = array(5,2,3);
if($array1 === array_intersect($array1, $array2) && $array2 === array_intersect($array2, $array1)) {
    echo 'Equal';
} else {
    echo 'Not equal';
}

Here's a version that works also with multidimensional arrays using http://php.net/manual/en/function.array-uintersect.php:

$array1 = array(
    array(5, 2),
    array(3, 6),
    array(2, 9, 4)
);
$array2 = array(
    array(3, 6),
    array(2, 9, 4),
    array(5, 2)
);

if($array1 === array_uintersect($array1, $array2, 'compare') && $array2 === array_uintersect($array2, $array1, 'compare')) {
    echo 'Equal';
} else {
    echo 'Not equal';
}

function compare($v1, $v2) {
    if ($v1===$v2) {
        return 0;
    }
    if ($v1 > $v2) return 1;
    return -1;
}
whitebrow
  • 1,610
  • 16
  • 21
3

Syntax problem on your arrays

$array1 = array(
    'a' => 'value1',
    'b' => 'value2',
    'c' => 'value3',
 );

$array2 = array(
    'a' => 'value1',
    'b' => 'value2',
    'c' => 'value3',
 );

$diff = array_diff($array1, $array2);

var_dump($diff); 
Syscall
  • 16,959
  • 9
  • 22
  • 41
3

array_diff — Computes the difference of arrays

http://php.net/manual/en/function.array-diff.php

array array_diff ( array $array1 , array $array2 [, array $... ] )

Compares array1 against one or more other arrays and returns the values in array1 that are not present in any of the other arrays.

Community
  • 1
  • 1
Scherbius.com
  • 3,292
  • 4
  • 21
  • 44
  • 6
    The OP wants to "check if two arrays are equal". `array_diff` can't tell you that. Try `array_diff([1, 2], [1, 2, 'hello'])`. – marcv Dec 02 '16 at 18:44
2

One way: (implementing 'considered equal' for http://tools.ietf.org/html/rfc6902#section-4.6)

This way allows associative arrays whose members are ordered differently - e.g. they'd be considered equal in every language but php :)

// recursive ksort
function rksort($a) {
  if (!is_array($a)) {
    return $a;
  }
  foreach (array_keys($a) as $key) {
    $a[$key] = ksort($a[$key]);
  }
  // SORT_STRING seems required, as otherwise
  // numeric indices (e.g. "0") aren't sorted.
  ksort($a, SORT_STRING);
  return $a;
}


// Per http://tools.ietf.org/html/rfc6902#section-4.6
function considered_equal($a1, $a2) {
  return json_encode(rksort($a1)) === json_encode(rksort($a2));
}
Mike McCabe
  • 985
  • 8
  • 9
2

Here is the example how to compare to arrays and get what is different between them.

$array1 = ['1' => 'XXX', 'second' => [
            'a' => ['test' => '2'],
            'b' => 'test'
        ], 'b' => ['no test']];

        $array2 = [
            '1' => 'XX',
            'second' => [
                'a' => ['test' => '5', 'z' => 5],
                'b' => 'test'
            ],
            'test'
        ];


        function compareArrayValues($arrayOne, $arrayTwo, &$diff = [], $reversed = false)
        {
            foreach ($arrayOne as $key => $val) {
                if (!isset($arrayTwo[$key])) {
                    $diff[$key] = 'MISSING IN ' . ($reversed ? 'FIRST' : 'SECOND');
                } else if (is_array($val) && (json_encode($arrayOne[$key]) !== json_encode($arrayTwo[$key]))) {
                    compareArrayValues($arrayOne[$key], $arrayTwo[$key], $diff[$key], $reversed);
                } else if ($arrayOne[$key] !== $arrayTwo[$key]) {
                    $diff[$key] = 'DIFFERENT';
                }
            }
        }

        $diff = [];
        $diffSecond = [];

        compareArrayValues($array1, $array2, $diff);
        compareArrayValues($array2, $array1, $diffSecond, true);

        print_r($diff);
        print_r($diffSecond);

        print_r(array_merge($diff, $diffSecond));

Result:

Array
(
    [0] => DIFFERENT
    [second] => Array
        (
            [a] => Array
                (
                    [test] => DIFFERENT
                    [z] => MISSING IN FIRST
                )

        )

    [b] => MISSING IN SECOND
    [1] => DIFFERENT
    [2] => MISSING IN FIRST
)
Marko Šutija
  • 346
  • 3
  • 8
1

Use php function array_diff(array1, array2);

It will return a the difference between arrays. If its empty then they're equal.

example:

$array1 = array(
    'a' => 'value1',

    'b' => 'value2',

    'c' => 'value3'
 );

$array2 = array(
    'a' => 'value1',

    'b' => 'value2',

    'c' => 'value4'
 );

$diff = array_diff(array1, array2);

var_dump($diff); 

//it will print array = (0 => ['c'] => 'value4' ) 

Example 2:

$array1 = array(
    'a' => 'value1',

    'b' => 'value2',

    'c' => 'value3',
 );

$array2 = array(
    'a' => 'value1',

    'b' => 'value2',

    'c' => 'value3',
 );

$diff = array_diff(array1, array2);

var_dump($diff); 

//it will print empty; 
Wolfgang Leon
  • 572
  • 7
  • 20
  • 1
    Technically, it does not return the difference between arrays. The documentation states "Compares array1 against one or more other arrays and returns the values in array1 that are not present in any of the other arrays.". So, if all the values from array1 are present in array2, even if array2 has more values, array_diff will return an empty array – 2pha Jun 13 '16 at 07:04
  • Does not "print null", prints an empty array (after fixing about a dozen syntax errors). Maybe you could use `(count(array_diff($a1, $a2)) + count(array_diff($a2, $a1))) === 0` to test if arrays are "equal" – user9645 Feb 03 '17 at 14:42
  • I fixed the syntax ( not null is empty, and I was mixing commas -.- ). What you're proposing I think is too much. Checking if its an empty array should be enough. – Wolfgang Leon Feb 03 '17 at 17:17
1

If you want to check non associative arrays, here is the solution:

$a = ['blog', 'company'];
$b = ['company', 'blog'];

(count(array_unique(array_merge($a, $b))) === count($a)) ? 'Equals' : 'Not Equals';
// Equals
Santo Boldizar
  • 907
  • 10
  • 14
  • i got 'Equals' for the following: `$a = array('a', 'b', 'c', 'd');` `$b = array('a', 'c', 'b');` `echo (count(array_unique(array_merge($a, $b))) === count($a)) ? 'Equals' : 'Not Equals';` – backbone Jul 23 '20 at 12:19
0

The following solution works with custom equality functions that you can pass as a callback. Note that it doesn't check arrays order.

trait AssertTrait
{
    /**
     * Determine if two arrays have the same elements, possibly in different orders. Elements comparison function must be passed as argument.
     *
     * @param array<mixed> $expected
     * @param array<mixed> $actual
     *
     * @throws InvalidArgumentException
     */
    public static function assertArraysContainSameElements(array $expected, array $actual, callable $comparisonFunction): void
    {
        Assert::assertEquals(\count($expected), \count($actual));

        self::assertEveryElementOfArrayIsInAnotherArrayTheSameAmountOfTimes($expected, $actual, $comparisonFunction);
        self::assertEveryElementOfArrayIsInAnotherArrayTheSameAmountOfTimes($actual, $expected, $comparisonFunction);
    }

    /**
     * @param array<mixed> $needles
     * @param array<mixed> $haystack
     *
     * @throws InvalidArgumentException
     */
    private static function assertEveryElementOfArrayIsInAnotherArrayTheSameAmountOfTimes(
        array $needles,
        array $haystack,
        callable $comparisonFunction
    ): void {
        Assert::assertLessThanOrEqual(\count($needles), \count($haystack));

        foreach ($needles as $expectedElement) {
            $matchesOfExpectedElementInExpected = \array_filter(
                $needles,
                static fn($element): bool => $comparisonFunction($expectedElement, $element),
            );

            $matchesOfExpectedElementInActual = \array_filter(
                $haystack,
                static fn($element): bool => $comparisonFunction($expectedElement, $element),
            );

            Assert::assertEquals(\count($matchesOfExpectedElementInExpected), \count($matchesOfExpectedElementInActual));
        }
    }
}

I usually use it in database integrations tests when I want to ensure that the expected elements are returned but I don't care about the sorting.