PHP强制数组键存在于返回类型中

I am working with a legacy application where methods are returning some large associative arrays.

When adding functionality, it is very difficult to read / understand because whilst developing, it is difficult to establish without effort whether the correct array keys are being returned by each method in a given class.

I am aware that by programming to an interface, you are enforcing a contract - great, but doesn't solve the problem of enforcing return types.

Further, if the return type is an associative array, I need a way of programatically throwing an exception if the returned array does not contain the correct array keys.

Aside from creating a validation class as an in-between layer is there a sensible way of enforcing what is returned inside an associative array?

Say you have a legacy method returning array with keys foo and bar:

function some()
    {
    return array('foo' => 'x', 'bar' => 2);
    }

You need to ensure that this array needs to have also bar and qux keys because legacy code is not extendable and... you just need it. Process the method's response like on the listing below:

function ensure(array $arr)
    {
    $keys = array('foo', 'bar', 'baz', 'qux');

    return array_merge(array_fill_keys($keys, null), $arr);
    }

$expected = ensure(some());

This way all values set in $arr will replace default nulls in array and you won't run into "key not exists" errors. You can of couse use that array_merge() call standalone, wrap legacy method with some decorator, but the solution stands either way.

If you want to throw exception when legacy method does not return something, you can similarly utilize array_diff_key():

function check(array $arr)
    {
    $keys = array('foo', 'bar', 'baz', 'qux');

    if(array_diff_key(array_fill_keys($keys, null), $arr)
        {
        throw new \RuntimeException('Invalid data returned!');
        }
    }

$expected = ensure(some());