371

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
  • 75
  • 8
markzzz
  • 47,390
  • 120
  • 299
  • 507

20 Answers20

689
$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
  • 82,642
  • 24
  • 155
  • 189
  • 105
    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
  • 7
    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
  • 2
    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
  • 58
    @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
  • 42
    @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
    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
119

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
  • 34,531
  • 8
  • 55
  • 100
lepe
  • 24,677
  • 9
  • 99
  • 108
  • 4
    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
  • 11
    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
  • 3
    might be worth adding count($a) == count($b) too – stefan Sep 07 '16 at 10:20
  • 3
    @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
  • 9
    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
40

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
  • 409
  • 4
  • 2
  • 10
    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
  • 2
    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
  • 1
    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
  • do not work if values are in different order or keys are in different order. – devsmt Nov 15 '22 at 13:33
37

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
  • 991
  • 10
  • 16
  • Good choice! But note, that this method uses strict types comparsion, so if you want to compare [1,2,3] and ['1','2','3'] result would be false. – ChronoExp Jun 25 '20 at 20:02
  • Note that this won't work with numerically indexed arrays where you care about the index value. [array_multisort()](https://www.php.net/manual/en/function.array-multisort.php) which will re-index numeric keys. – Costa May 25 '22 at 05:38
  • 1
    This is a good answer comparing to others, but it doesn't cover the case where nested arrays have the keys in different order. – Vasiliy Artamonov Oct 17 '22 at 09:38
  • Good answer, but will not handle this case: `array_equal( ['aa' =>['bb' => 'b', 'aa' => 'a']], ['aa' =>['aa' => 'a', 'bb' => 'b']] )` – devsmt Nov 15 '22 at 13:53
18
function compareIsEqualArray(array $array1,array $array2):bool
{

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

}
Kris Erickson
  • 33,454
  • 26
  • 120
  • 175
dılo sürücü
  • 3,821
  • 1
  • 26
  • 28
15

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
  • 90,431
  • 16
  • 141
  • 175
9
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.

  • I'sorry, this will not handle the case `array_equal([0], [false])` and `array_equal([1, 2, 2], [2, 1, 1])`. – devsmt Nov 15 '22 at 14:02
5

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
  • 2,015
  • 21
  • 24
  • I'm sorry, this can't handle `array_equal([1, 2, 2], [2, 1, 1])` and multi dimensional associative arrays with keys in different order. – devsmt Nov 15 '22 at 14:06
2

One way: (implementing 'considered equal' for https://www.rfc-editor.org/rfc/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 https://www.rfc-editor.org/rfc/rfc6902#section-4.6
function considered_equal($a1, $a2) {
  return json_encode(rksort($a1)) === json_encode(rksort($a2));
}
Community
  • 1
  • 1
Mike McCabe
  • 1,015
  • 9
  • 9
  • 1
    I believe that you it should be: `$a[$key] = rksort($a[$key]);` – pinkeen Apr 08 '15 at 11:24
  • Thanks for your contribution, but this can't handle `array_equal([0, 1], [1, 0])` and `array_equal([1, 2, 2], [2, 2, 1])`. – devsmt Nov 15 '22 at 14:12
  • `[0, 1]` and `[1, 0]` are not identical so this answer is not expected to return true for that. The scope of this page has crept away from the asker's requirements for years. – mickmackusa Nov 22 '22 at 19:59
2

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
  • 19,327
  • 10
  • 37
  • 52
2

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,396
  • 4
  • 24
  • 44
  • 12
    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

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
  • 345
  • 3
  • 9
  • This basically relies on the !== operator that can't handle different order of elements or keys and check the value type. – devsmt Nov 15 '22 at 14:18
2

Given:

$array1 = ['a', 'b', '3'];
$array2 = ['a', 'b', '3'];

$array1 == $array2  //true
$array1 === $array2 //true

Given:

$array1 = ['a', 'b', 3];
$array2 = ['a', 'b', '3'];

$array1 == $array2  //true
$array1 === $array2 //false

Given:

$array1 = ['3', 'a', 'b'];
$array2 = ['a', 'b', '3'];

$array1 == $array2  //false
$array1 === $array2 //false

The solution, sort in same order

$array1 = ['3', 'a', 'b'];
$array2 = ['a', 'b', '3'];

sort($array1);
sort($array2);

$array1 == $array2  //true
$array1 === $array2 //true
Emeka Mbah
  • 16,745
  • 10
  • 77
  • 96
0

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
  • 1,255
  • 14
  • 17
  • 3
    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.

0

The proper way to compare whether two arrays are equal is to use strict equality (===), which compares recursively. Existing answers are unable to recursively sort an arbitrary array (array of arbitrary depth and order, containing a mixture of sequential and associative arrays) and hence cannot handle comparisons of arbitrary arrays. Sequential arrays are associative arrays with a sequential key (0,1,2,3...) whereas associative arrays do not have a sequential key.

To sort these arbitrary arrays, we have to:

  1. Traverse downwards towards leaf nodes with no more sub-arrays
  2. Sort sequential arrays by serializing then sorting them (to remove the need of having to use custom comparators)
  3. Sort associative arrays by key

The following code implements the solution described above. Improvements to the code are welcome.

function recur_sort( &$array ) {
    foreach ( $array as &$value ) {
       if ( is_array( $value ) ) recur_sort( $value );
    }

    if ( is_sequential_array( $array ) ) {
        $array = array_map( function( $el ) { return json_encode( $el ); }, $array  );
        sort( $array, SORT_STRING );
        $array = array_map( function( $el ) { return json_decode( $el, true ); }, $array  );
        return;
    } else {
        return ksort( $array );
    }
}

function is_sequential_array(Array &$a) {
    $n = count($a);
    for($i=0; $i<$n; $i++) {
        if(!array_key_exists($i, $a)) {
            return false;
        }
    }
    return true;
}

Example (in PHPUnit):

//A stricter and recursive assertEqualsCanonicalizing
public function assertSameCanonicalizing( $expected, $actual ) {
    recur_sort( $expected );
    recur_sort( $actual );
    $this->assertSame( $expected, $actual );
}
Toh Nic
  • 21
  • 3
0

If you want to check that your arrays have the strictly equal (===) associations of keys and values, you can use the following function:

function array_eq($a, $b) {
    // If the objects are not arrays or differ in their size, they cannot be equal
    if (!is_array($a) || !is_array($b) || count($a) !== count($b)) {
        return false;
    }
    // If the arrays of keys are not strictly equal (after sorting),
    // the original arrays are not strictly equal either
    $a_keys = array_keys($a);
    $b_keys = array_keys($b);
    array_multisort($a_keys);
    array_multisort($b_keys);
    if ($a_keys !== $b_keys) {
        return false;
    }
    // Comparing values
    foreach ($a_keys as $key) {
        $a_value = $a[$key];
        $b_value = $b[$key];
        // Either the objects are strictly equal or they are arrays
        // which are equal according to our definition. Otherwise they
        // are different.
        if ($a_value !== $b_value && !array_eq($a_value, $b_value)) {
            return false;
        }
    }
    return true;
}
0

To compare the values of your arrays, also multidimensional, associative and in any combination:

/**
 * @see PHPUnit Assert::assertEqualsCanonicalizing()
 * @return true if all keys and values are equal and of the same type,
 * irregardless of items or keys order
 */
function array_vals_equal(array $a, array $b): bool {
    // sort multi-dimensional recursive
    $_deep_sort = function (array $a) use (&$_deep_sort): array{
        // sort discarding index association or sort keys, depending on array type
        array_is_list($a) ? sort($a) : ksort($a);
        return array_map(fn($v) => is_array($v) ? $_deep_sort($v) : $v, $a);
    };
    // operator === checks that the count, types and order of the elements are the same
    return $_deep_sort($a) === $_deep_sort($b);
}
// Test cases
assertEquals(array_vals_equal([1], [1]), true, 'simple eq');
assertEquals(array_vals_equal([0], [false]), false, 'simple eq');
assertEquals(array_vals_equal([0], [null]), false, 'simple eq');
assertEquals(array_vals_equal([0, 1], [1, 0]), true, 'simple eq, diff order');
assertEquals(array_vals_equal([0, 1, 2], [1, 0]), false, 'diff count');
assertEquals(array_vals_equal([0, 1], [0, 1, 2]), false, 'diff count 2');
assertEquals(array_vals_equal([1, 2], [1, 2, 'hello']), false, 'diff count 3');
//
assertEquals(array_vals_equal([1, 2, 2], [2, 1, 1]), false, 'same vals repeated');
assertEquals(array_vals_equal([1, 2, 2], [2, 2, 1]), true, 'same vals, different order');
//
assertEquals(array_vals_equal([1, 2, 3], ['1', '2', '3']), false, 'int should not be eq string');
assertEquals(array_vals_equal([0 => 'a', 1 => 'b'], [0 => 'b', 1 => 'a']), true, 'same vals, diff order');
assertEquals(array_vals_equal(['a', 'b'], [3 => 'b', 5 => 'a']), true, 'same vals, diff indexes');
// associative arrays whose members are ordered differently
assertEquals(array_vals_equal(['aa' => 'a', 'bb' => 'b'], ['bb' => 'b', 'aa' => 'a']), true, 'dict with different order');
assertEquals(array_vals_equal(['aa' => 'a', 'bb' => 'b'], ['aa' => 'a']), false, 'a key is missing');
assertEquals(array_vals_equal(['aa' => 'a', 'bb' => 'b'], ['aa' => 'a', 'zz' => 'b']), false, 'dict same vals diff key');
// nested arrays with keys in different order
assertEquals(array_vals_equal(
    ['aa' => 'a', 'bb' => ['bb' => 'b', 'aa' => 'a']],
    ['aa' => 'a', 'bb' => ['aa' => 'a', 'bb' => 'b']]
), true, 'dict multi 2 level, keys in different order');
assertEquals(array_vals_equal(
    ['aa' => 'a', 'bb' => ['aa2' => 'a', 'bb2' => ['aa3' => 'a', 'bb3' => 'b']]],
    ['aa' => 'a', 'bb' => ['aa2' => 'a', 'bb2' => ['aa3' => 'a', 'bb3' => 'b']]]
), true, 'dict multi 3 level');
assertEquals(array_vals_equal(
    ['aa' => 'a', 'bb' => [0, 1]],
    ['aa' => 'a', 'bb' => [1, 0]]
), true, 'dict multi level, 2^ level sequential in different order');
assertEquals(array_vals_equal([[0, 1], ['a', 'b']], [['b', 'a'], [1, 0]]), true, 'multi level sequential');
devsmt
  • 56
  • 1
  • 4
  • I see "_I'd like to check if two arrays are equal. I mean: same size, same index, same values._" I don't see where the asker wants to recursively sort the values IF the array is a list. Why have you deviated from the asked question? Perhaps you should find a more suitable page or ask a new question that distinctly asks for this behavior. Otherwise, researchers may be confused by your answer while trying to compare it against other answers (apples to oranges). – mickmackusa Nov 15 '22 at 21:46
  • To sort sub arrays is needed if you want to compare them by values, in other words the case `array_equal( [[0, 1]], [[1, 0]] )` can't be satisfied without. This case is not mentioned by the original question but comes from a comment by another user that I think is the right interpretation of the requirements. It says "same values", so sub arrays should be treated with the same rules. – devsmt Nov 16 '22 at 14:34
  • Providing a solution for some random commenters is not a good reason to extend the scope of the original question. All answers are expected to resolve the single asked question at the top of this page. – mickmackusa Nov 16 '22 at 19:55
  • The scope of the original question is "Check if two arrays are equal". Generic arrays, of any kind. But feel free to use in the software you are responsible a comparison function that fails for such common use case. – devsmt Nov 22 '22 at 16:40
  • Incorrect. The scope is: "_I'd like to check if two arrays are equal. I mean: same size, same index, same values._" The title is: "_Check if two arrays are equal_" There will be thousands upon thousands of pages on SO with generalized titles (due to a number of factors). Do not answer the title, answer the question. – mickmackusa Nov 22 '22 at 19:56
0

If you'd like to generate a detailed report, you could use something like this:

function deepCompare(Array $a, Array $b, string $parentAKey, string $parentBKey, bool $compareInverted = true, bool $compareValues = true, string $log = '')
{
    foreach ($a as $aKey => $aValue) {
        $fullAKey = implode('.', [$parentAKey, $aKey]);
        $fullBKey = implode('.', [$parentBKey, $aKey]);
        if (! isset($b[$aKey])) {
            $log .= "⍰ {$fullAKey} has no equivalent {$fullBKey}\n";
        } else {
            $bValue = $b[$aKey];
            if (is_array($aValue)) {
                $log = deepCompare($aValue, $bValue, $fullAKey, $fullBKey, false, $compareValues, $log);
            } else {
              if ($compareValues) {
                  if ($aValue != $bValue) {
                      $log .= "≠ {$fullAKey} value differs from {$fullBKey}\n";
                  }
              }
            }
        }
    }
    if ($compareInverted) {
        $log = deepCompare($b, $a, $parentBKey, $parentAKey, false, false, $log);
    }
    return $log;
}

Here is an example for it:

$november = [
  'site1' => [
    'id' => 15,
    'name' => 'Brazil',
    'extendedHours' => 454,
  ],
  'site2' => [
    'id' => 43,
    'name' => 'Portugal',
    'extendedHours' => 448,
  ],
  'site3' => [
    'id' => 49,
    'name' => 'Spain',
    'extendedHours' => 0,
  ],  
  'totalExtendedHours' => 902,
];

$december = [
  'site1' => [
    'id' => 15,
    'name' => 'Brazil',
    'extendedHours' => 498,
  ],
  'site2' => [
    'id' => 43,
    'name' => 'Portugal',
    'extendedHours' => 409,
    'extraRequests' => 6,
  ],
  'totalExtendedHours' => 907,
  'totalExtraRequests' => 6,
];

echo deepCompare(
    $november,    -- origin array
    $december,    -- target array
    'Nov2022',    -- descriptive name of origin array
    'Dec2022',    -- descriptive name of target array
    true,         -- should also compare arrays in reverse order?
    true          -- should care about array values? (false = names only)
);

This example will output:

≠ Nov2022.site1.extendedHours value differs from Dec2022.site1.extendedHours
≠ Nov2022.site2.extendedHours value differs from Dec2022.site2.extendedHours
⍰ Nov2022.site3 has no equivalent Dec2022.site3
≠ Nov2022.totalExtendedHours value differs from Dec2022.totalExtendedHours
⍰ Dec2022.site2.extraRequests has no equivalent Nov2022.site2.extraRequests
⍰ Dec2022.totalExtraRequests has no equivalent Nov2022.totalExtraRequests

I hope that helps someone.

ari.webber
  • 21
  • 3
-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
  • 695
  • 9
  • 20
  • 3
    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
  • 1
    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