Forming error messages from a multidimensional associative array I'm working with an input array, which is 3 levels deep, and creating error message strings accordingly in a separate output array.  Below is the code.

$e['invalid']['key'][] = 'a123';
$e['invalid']['key'][] = 'a456';
$e['invalid']['color'][] = 'red';
$e['missing']['key'][] = 'b72';
$e['missing']['color'][] = 'blue';
$e['missing']['color'][] = 'green';
echo '&lt;pre&gt;' . print_r($e, 1) . '&lt;/pre&gt;';


function generateErrorMessages($e)
{
    $errors;
    foreach ($e as $type =&gt; $array)
    {
        foreach ($array as $key =&gt; $values)
        {               
            foreach ($values as $v)
            {
                switch($type)
                {
                    case 'invalid':
                                    $errors[$type][$key][] = $v . ' is not a valid ' . $key;
                                    break;
                    case 'missing':
                                    $errors[$type][$key][] = $v . ' is a required ' . $key . ' - other functions have dependencies on it';
                                    break;
                    default:        
                                    // do nothing                   
                }
            }
        }
    }
    return $errors;
}

$msgs = generateErrorMessages($e);
echo '&lt;pre&gt;' . print_r($msgs, 1) . '&lt;/pre&gt;';


While this achieves the desired outcome, the nested foreach loops in the generateErrorMessages() method seem onerous and difficult to read.  Is there a more concise way to generate the error messages?

Here is a screenshot of the input array:


Here is a screenshot of the output array:
In my opinion, this code is all right.  As any explicit code, these loops are quite straightforward to follow. And making it more concise will likely make it more cryptic as well. I would only make a minor brush-up, removing the unnecessary default clause and make the proper indentation. Variable interpolation is also more natural to read, in my opinion.

Also, variables must be explicitly initialized, just a mention is not enough. If you need an empty array then you must initialize an empty array. Although in the present code the $errors variable doesn't exist before the loop, the code could evolve over time, and there could be the possibility that a variable with the same name will be used above. If you just mention it, as $errors; it will keep the previous value. If you initialize it as $errors = []; you will always know it's an empty array. 

function generateErrorMessages($e)
{
    $errors = [];
    foreach ($e as $type =&gt; $array)
    {
        foreach ($array as $key =&gt; $values)
        {               
            foreach ($values as $v)
            {
                switch($type)
                {
                    case 'invalid':
                        $errors[$type][$key][] = "$v is not a valid $key";
                        break;
                    case 'missing':
                        $errors[$type][$key][] = "$v is a required $key - other functions have dependencies on it";
                        break;
                }
            }
        }
    }
    return $errors;
}