1

Possible Duplicate:
recursive array_diff()?

I have a static multidimensional array which is always going to be in the same form. E.g. it will have the same keys & hierarchy.

I want to check a posted array to be in the same 'form' as this static array and if not error.

I have been trying various methods but they all seem to end up with a lot of if...else components and are rather messy.

Is there a succinct way to achieve this?


In response to an answer from dfsq:

$etalon = array(
    'name' => array(),
    'income' => array(
        'day'   => '',
        'month' => array(),
        'year'  => array()
    ),
    'message' => array(),
);

$test = array(
    'name' => array(),
    'income' => array(
        'day'   => '',
        'month' => array(),
        'year'  => array()
    ),
    'message' => array(),
);

// Tests
$diff = array_diff_key_recursive($etalon, $test);
var_dump(empty($diff));
print_r($diff);

And the results from that are

bool(false) 
Array ( [name] => 1 [income] => Array ( [month] => 1 [year] => 1 ) [message] => 1 ) 
0

4 Answers 4

5

Author needs a solution which would test if the structure of the arrays are the same. Next function will make a job.

/**
 * $a1 array your static array.
 * $a2 array array you want to test.
 * @return array difference between arrays. empty result means $a1 and $a2 has the same structure.
 */ 
function array_diff_key_recursive($a1, $a2)
{
    $r = array();

    foreach ($a1 as $k => $v)
    {
        if (is_array($v))
        {
            if (!isset($a2[$k]) || !is_array($a2[$k]))
            {
                $r[$k] = $a1[$k];
            }
            else
            {
                if ($diff = array_diff_key_recursive($a1[$k], $a2[$k]))
                {
                    $r[$k] = $diff;
                }
            }
        }
        else
        {
            if (!isset($a2[$k]) || is_array($a2[$k]))
            {
                $r[$k] = $v;
            }
        }
    }

    return $r;
}

And test it:

$etalon = array(
    'name' => '',
    'income' => array(
        'day'   => '',
        'month' => array(),
        'year'  => array()
    ),
    'message' => ''
);

$test = array(
    'name' => 'Tomas Brook',
    'income' => array(
        'day'   => 123,
        'month' => 123,
        'year'  => array()
    )
);

// Tests
$diff = array_diff_key_recursive($etalon, $test);
var_dump(empty($diff));
print_r($diff);

This will output:

bool(false)
Array
(
    [income] => Array
    (
        [month] => Array()

    )

    [message] => 
)

So checking for emptiness of $diff array will tell you if arrays have the same structure.

Note: if you need you can also test it in other direction to see if test array has some extra keys which are not present in original static array.

Sign up to request clarification or add additional context in comments.

9 Comments

Thanks I am giving this a go currently!
Hi there, this doesnt seem to work properly im afraid. When the you put the $a1 & $a2 as the same structure it still gives an output of Array ( [income] => Array ( [month] => 1 [year] => 1 ) ) Which suggests it has a problem with the empty arrays of 'month' & 'year' in the $a1 array.
Well if you define $a1 = Array([income] => Array( [month] => Array() [year] => Array() ) ), then its structure differs from $a2 = Array([income] => Array( [month] => 1 [year] => 1 ) ), because 1 is a scalar, not an array. If I understand what you mean.
Sorry, the Array ( [income] => Array ( [month] => 1 [year] => 1 ) ) was the return from the function e.g. it thought they were different.
Could you post the example of your arrays so that I could see? Because for my arrays function works fine..
|
3

You could user array_intersect_key() to check if they both contain the same keys. If so, the resulting array from that function will contain the same values as array_keys() on the source array.

AFAIK those functions aren't recursive, so you'd have to write a recursion wrapper around them.

See User-Notes on http://php.net/array_diff_key

1 Comment

Hi, cheers for that I am going to give this a go and post the results in a bit.
1

Are you searching for the array_diff or array_diff_assoc functions?

Comments

0

use foreach with the ifs...if u have different tests for the different inner keys eg

$many_entries = ("entry1" = array("name"=>"obi", "height"=>10));   

and so on, first define functions to check the different keys then a foreach statement like this

foreach($many_entries as $entry)
    { 
        foreach($entry as $key => $val) 
            {
                switch($key)
                    {
                        case "name": //name function
                            //and so on
                    }
            }
    }

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.