PHP - 检查两个数组是否相等

PHP - Check if two arrays are equal

提问人:markzzz 提问时间:4/15/2011 最后编辑:izekemarkzzz 更新时间:3/28/2023 访问量:455616

问:

我想检查两个数组是否相等。我的意思是:相同的大小,相同的索引,相同的值。我该怎么做?

按照用户的建议使用,如果数组中至少有一个元素不同,我希望以下内容会打印回车符,但实际上并非如此。!==

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

    echo "enter";
}
PHP 数组

评论

19赞 jeroen 4/16/2011
你用得太多了,它应该是或=!==!=
37赞 teynon 6/6/2013
仅供记录(因为我的编辑已更改回“用户”),它是“用户”:english.stackexchange.com/questions/105116/...

答:

2赞 Scherbius.com 4/15/2011 #1

array_diff — 计算数组的差值

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

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

与一个或多个其他数组进行比较,并返回任何其他数组中不存在的值。array1array1

评论

12赞 marcv 12/3/2016
OP 想要“检查两个数组是否相等”。 不能告诉你。尝试。array_diffarray_diff([1, 2], [1, 2, 'hello'])
15赞 Emil Vikström 4/15/2011 #2

将它们与其他值进行比较:

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

您可以在此处阅读有关所有数组运算符的信息: 例如 http://php.net/manual/en/language.operators.array.php 注意,它还检查数组中元素的类型和顺序是否相同。===

评论

7赞 Matthew Flaschen 4/15/2011
或者取决于所需的行为。===
699赞 Stefan Gehrig 4/15/2011 #3
$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.

请参见数组运算符

编辑

不等式运算符是,而非恒等运算符是匹配等式 operator 和标识 operator 。!=!=======

评论

106赞 trejder 9/23/2013
旁注:这种方法也适用于多维数组(以前对我来说并不那么明显)。
8赞 Peter Krauss 10/15/2014
PS:解决方案是使用...另一个常见的问题是关于唯一值,所以请记住 存在 .array_values($a)==array_values($b)array_unique()
2赞 Andrew 8/1/2015
说 == 检查匹配的键/值对有点误导。它似乎实际上检查了值 == 彼此。因此,您可能会惊讶地发现 array(0) == array('not zero') 为 true。
59赞 Stefan Gehrig 11/15/2015
@nawfal:你的假设是错误的。 是一个数组,而 是一个数组。这就是为什么它们没有与我的答案中所述相同的键/值对的原因,这就是为什么它们在它们之间不起作用的原因。['a', 'b'][0 => 'a', 1 => 'b']['b', 'a'][0 => 'b', 1 => 'a']==
42赞 nawfal 11/15/2015
@StefanGehrig哦,你是对的。我将留下我的评论,以表明我的愚蠢:)
40赞 Iggi 7/15/2011 #4

尝试序列化。这也将检查嵌套的子数组。

$foo =serialize($array_foo);
$bar =serialize($array_bar);
if ($foo == $bar) echo "Foo and bar are equal";

评论

10赞 Kevin Peno 8/22/2013
如果键和值像使用比较一样移动,则有问题。但是,假设它们预计 100% 相同,这是检查深度相等的最干净、最简单的方法!
2赞 Rafael Moni 7/24/2014
我想这是最好的解决方案!它可以比较多维数组和关联数组(如果它们之前被排序过)!
1赞 Pablo Pazos 10/21/2020
如果数组被视为 SET,则不起作用:它应该在所有嵌套级别上排序,以便能够检查是否以任何顺序包含相同的项目。
0赞 devsmt 11/15/2022
如果值的顺序不同或键的顺序不同,则不起作用。
119赞 lepe 8/3/2011 #5

根据此页面

注意:接受的答案适用于关联数组,但对于索引数组(如下所述),它不会像预期的那样工作。如果要比较其中任何一个,请使用此解决方案。此外,此函数可能不适用于多维数组(由于array_diff函数的性质)。

测试两个索引数组,哪些元素的顺序不同,使用或失败,例如:$a == $b$a === $b

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

这是因为上述含义是:

array(0 => "x", 1 => "y")与。。array(0 => "y", 1 => "x")

要解决该问题,请使用:

<?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)
    );
}
?>

添加了比较数组大小(由 super_ton 建议),因为它可以提高速度。

评论

4赞 maersu 4/10/2014
注意:多维数组无法按预期工作
11赞 Ghola 9/8/2014
上述评论是错误的。如果$b具有$a具有的所有元素以及一些额外的元素,则这两个数组不相等,但上面的代码会说它们相等。
3赞 stefan 9/7/2016
可能也值得添加 count($a) == count($b)
3赞 lepe 9/8/2016
@super_ton:是的,在打电话之前可以加快比较速度。我会添加它。谢谢array_diff
9赞 AwesomeGuy 9/28/2018
不幸的是,它在某些情况下不起作用,例如,我已经用以下情况进行了测试,它返回了 ,但这两个数组显然不相同。$a = [1, 2, 2]; $b = [2, 1, 1];true
2赞 Mike McCabe 6/10/2014 #6

一种方法:(对 https://www.rfc-editor.org/rfc/rfc6902#section-4.6 实现“被认为是平等的”)

这种方式允许其成员排序不同的关联数组 - 例如,它们在每种语言中都被认为是相等的,但 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));
}

评论

1赞 pinkeen 4/8/2015
我相信你应该是:$a[$key] = rksort($a[$key]);
0赞 devsmt 11/15/2022
感谢您的贡献,但这无法处理和.array_equal([0, 1], [1, 0])array_equal([1, 2, 2], [2, 2, 1])
0赞 mickmackusa 11/23/2022
[0, 1]并且不相同,因此此答案预计不会返回 true。多年来,此页面的范围已经从提问者的要求中悄然消失。[1, 0]
5赞 whitebrow 9/28/2015 #7

另一种检查相等性的方法,无论值顺序如何,都是通过使用 http://php.net/manual/en/function.array-intersect.php,如下所示:

$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';
}

下面是一个版本,它也适用于使用 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;
}

评论

0赞 devsmt 11/15/2022
对不起,这无法处理具有不同顺序键的多维关联数组。array_equal([1, 2, 2], [2, 1, 1])
-1赞 Wolfgang Leon 3/15/2016 #8

使用php函数 array_diff(array1, array2);

它将返回数组之间的差值。如果它是空的,那么它们是相等的。

例:

$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' ) 

示例 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; 

评论

3赞 2pha 6/13/2016
从技术上讲,它不会返回数组之间的差值。该文档指出“将 array1 与一个或多个其他数组进行比较,并返回 array1 中任何其他数组中不存在的值。因此,如果 array1 中的所有值都存在于 array2 中,即使 array2 有更多值,array_diff也将返回一个空数组
1赞 user9645 2/3/2017
不“打印 null”,打印一个空数组(在修复了大约十几个语法错误之后)。也许你可以用它来测试数组是否“相等”(count(array_diff($a1, $a2)) + count(array_diff($a2, $a1))) === 0
0赞 Wolfgang Leon 2/4/2017
我修复了语法( not null 为空,我混合了逗号-.- )。我认为你的建议太多了。检查它是否为空数组就足够了。
37赞 Samuel Vicent 9/16/2016 #9

简短的解决方案,即使适用于以不同顺序给出键的数组:

public static function arrays_are_equal($array1, $array2)
{
    array_multisort($array1);
    array_multisort($array2);
    return ( serialize($array1) === serialize($array2) );
}

评论

0赞 ChronoExp 6/26/2020
不错的选择!但请注意,此方法使用严格的类型比较,因此如果要比较 [1,2,3] 和 ['1','2','3'] 结果将是错误的。
0赞 Costa 5/25/2022
请注意,这不适用于您关心索引值的数字索引数组。array_multisort(),它将重新索引数字键。
1赞 Vasiliy Artamonov 10/17/2022
与其他数组相比,这是一个很好的答案,但它没有涵盖嵌套数组具有不同顺序键的情况。
0赞 devsmt 11/15/2022
很好的答案,但不会处理这种情况:array_equal( ['aa' =>['bb' => 'b', 'aa' => 'a']], ['aa' =>['aa' => 'a', 'bb' => 'b']] )
2赞 YEFFOU WAGOUM THIERRY HENRI 3/20/2018 #10

数组上的语法问题

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

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

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

var_dump($diff); 
10赞 Marcos Fernandez Ramos 8/21/2018 #11
if (array_diff($a,$b) == array_diff($b,$a)) {
  // Equals
}

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

从我的 pov 来看,使用 array_diff 比array_intersect更好,因为通过这种性质的检查,返回的差异通常小于相似性,这样 bool 转换就不那么占用内存了。

编辑请注意,此解决方案适用于普通数组,并补充了上面发布的 == 和 === 仅对字典有效的解决方案。

评论

0赞 devsmt 11/15/2022
对不起,这不会处理案件和.array_equal([0], [false])array_equal([1, 2, 2], [2, 1, 1])
0赞 Santo Boldizar 2/22/2019 #12

如果要检查非关联数组,解决方案如下:

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

(count(array_unique(array_merge($a, $b))) === count($a)) ? 'Equals' : 'Not Equals';
// Equals

评论

3赞 backbone 7/23/2020
我得到了以下“等于”:$a = array('a', 'b', 'c', 'd'); $b = array('a', 'c', 'b'); echo (count(array_unique(array_merge($a, $b))) === count($a)) ? 'Equals' : 'Not Equals';
18赞 dılo sürücü 8/3/2019 #13
function compareIsEqualArray(array $array1,array $array2):bool
{

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

}

评论

2赞 k0pernikus 8/3/2019
解释代码示例正在做什么很有帮助。这是否也适用于多维数组?
2赞 dılo sürücü 8/3/2019
array_diff从数组中获取不同的元素array_diff如果返回空数组两个数组相等
0赞 Anand Singh 2/25/2022
array_diff 返回一个数组,其中包含 array1 中任何其他数组中不存在的条目
0赞 devsmt 11/15/2022
这无法处理这种情况和.array_equal([1, 2, 2], [2, 1, 1])array_equal([1, 2, 3], ['1', '2', '3'])
2赞 Marko Šutija 1/23/2020 #14

下面是如何与数组进行比较并获取它们之间的不同之处的示例。

$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));

结果:

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

        )

    [b] => MISSING IN SECOND
    [1] => DIFFERENT
    [2] => MISSING IN FIRST
)

评论

0赞 devsmt 11/15/2022
这基本上依赖于 !== 运算符,该运算符无法处理不同顺序的元素或键并检查值类型。
0赞 Lorenzo Franco Ranucci 5/1/2021 #15

以下解决方案适用于可作为回调传递的自定义相等函数。请注意,它不会检查数组顺序。

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));
        }
    }
}

当我想确保返回预期的元素时,我通常在数据库集成测试中使用它,但我不关心排序。

评论

0赞 devsmt 11/15/2022
谢谢你的贡献。对于这样一个基本功能来说,可能依赖太多了。
0赞 Toh Nic 9/9/2021 #16

比较两个数组是否相等的正确方法是使用严格相等 (===),它以递归方式进行比较。现有答案无法递归地对任意数组(任意深度和顺序的数组,包含顺序数组和关联数组的混合)进行排序,因此无法处理任意数组的比较。顺序数组是具有顺序键 (0,1,2,3...) 的关联数组,而关联数组没有顺序键。

要对这些任意数组进行排序,我们必须:

  1. 向下遍历到不再有子数组的叶节点
  2. 通过序列化然后对顺序数组进行排序来对它们进行排序(以消除必须使用自定义比较器的需要)
  3. 按键对关联数组进行排序

以下代码实现上述解决方案。欢迎对代码进行改进。

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;
}

示例(在 PHPUnit 中):

//A stricter and recursive assertEqualsCanonicalizing
public function assertSameCanonicalizing( $expected, $actual ) {
    recur_sort( $expected );
    recur_sort( $actual );
    $this->assertSame( $expected, $actual );
}
0赞 user14611663 12/29/2021 #17

如果要检查数组是否具有键和值的严格相等 () 关联,可以使用以下函数:===

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赞 devsmt 11/15/2022 #18

要比较数组的值,包括多维数组、关联数组和任意组合数组的值:

/**
 * @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');

评论

0赞 mickmackusa 11/16/2022
我看到“我想检查两个数组是否相等。我的意思是:相同的大小,相同的索引,相同的值。如果数组是一个列表,我不明白提问者想要在哪里递归地对值进行排序。你为什么偏离了被问的问题?也许你应该找到一个更合适的页面,或者问一个新问题,明确要求这种行为。否则,研究人员在尝试将其与其他答案(苹果到橙子)进行比较时可能会对您的答案感到困惑。
0赞 devsmt 11/16/2022
如果要按值比较子数组,则需要对子数组进行排序,换句话说,没有子数组就无法满足大小写。原始问题没有提到这种情况,而是来自另一个用户的评论,我认为这是对要求的正确解释。它说“相同的值”,因此子数组应该用相同的规则来处理。array_equal( [[0, 1]], [[1, 0]] )
0赞 mickmackusa 11/17/2022
为一些随机评论者提供解决方案并不是扩大原始问题范围的好理由。所有答案都应解决本页顶部的单个问题。
0赞 devsmt 11/23/2022
原始问题的范围是“检查两个数组是否相等”。任何类型的泛型数组。但是,请随意在您负责的软件中使用比较功能,该功能对于此类常见用例无效。
0赞 mickmackusa 11/23/2022
不對。范围是:“我想检查两个数组是否相等。我的意思是:相同的大小,相同的索引,相同的值。标题是:“检查两个数组是否相等” SO 上将有成千上万的页面带有通用标题(由于多种因素)。不要回答标题,回答问题。
0赞 ari.webber 1/26/2023 #19

如果您想生成详细报告,可以使用如下内容:

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;
}

下面是一个示例:

$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)
);

此示例将输出:

≠ 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

我希望这对某人有所帮助。

2赞 Emeka Mbah 3/28/2023 #20

鉴于:

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

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

鉴于:

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

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

鉴于:

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

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

解决方案,按相同顺序排序

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

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

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