指定されたキーのセットの値を無視しながら、2 つの配列が同じであることをアサートできる PHP 関数が必要です (値のみ、キーは一致する必要があります)。
実際には、配列は同じ構造でなければなりませんが、一部の値は無視できます。
たとえば、次の 2 つの配列を考えてみます。
Array
(
[0] => Array
(
[id] => 0
[title] => Book1 Title
[creationDate] => 2013-01-13 17:01:07
[pageCount] => 0
)
)
Array
(
[0] => Array
(
[id] => 1
[title] => Book1 Title
[creationDate] => 2013-01-13 17:01:07
[pageCount] => 0
)
)
key の値を無視すれば、それらは同じですid
。
また、ネストされた配列の可能性も考慮したいと思います。
Array
(
[0] => Array
(
[id] => 0
[title] => Book1 Title
[creationDate] => 2013-01-13 17:01:07
[pageCount] => 0
)
[1] => Array
(
[id] => 0
[title] => Book2 Title
[creationDate] => 2013-01-13 18:01:07
[pageCount] => 0
)
)
Array
(
[0] => Array
(
[id] => 2
[title] => Book1 Title
[creationDate] => 2013-01-13 17:01:07
[pageCount] => 0
)
[1] => Array
(
[id] => 3
[title] => Book2 Title
[creationDate] => 2013-01-13 18:01:07
[pageCount] => 0
)
)
テストに必要なので、PHPUnit_Framework_TestCaseを拡張し、アサート関数を使用する次のクラスを作成しました。
class MyTestCase extends PHPUnit_Framework_TestCase
{
public static function assertArraysSame($expected, $actual, array $ignoreKeys = array())
{
self::doAssertArraysSame($expected, $actual, $ignoreKeys, 1);
}
private static function doAssertArraysSame($expected, $actual, array $ignoreKeys = array(), $depth, $maxDepth = 256)
{
self::assertNotEquals($depth, $maxDepth);
$depth++;
foreach ($expected as $key => $exp) {
// check they both have this key
self::assertArrayHasKey($key, $actual);
// check nested arrays
if (is_array($exp))
self::doAssertArraysSame($exp, $actual[$key], $ignoreKeys, $depth);
// check they have the same value unless the key is in the to-ignore list
else if (array_search($key, $ignoreKeys) === false)
self::assertSame($exp, $actual[$key]);
// remove the current elements
unset($expected[$key]);
unset($actual[$key]);
}
// check that the two arrays are both empty now, which means they had the same lenght
self::assertEmpty($expected);
self::assertEmpty($actual);
}
}
doAssertArraysSame
配列の 1 つを反復処理し、2 つの配列が同じキーを持つことを再帰的にアサートします。また、現在のキーが無視するキーのリストにない限り、それらの値が同じであることも確認します。
2 つの配列の要素数が正確に同じであることを確認するために、反復中に各要素が削除され、ループの最後に、関数は両方の配列が空であることを確認します。
使用法:
class MyTest extends MyTestCase
{
public function test_Books()
{
$a1 = array('id' => 1, 'title' => 'the title');
$a2 = array('id' => 2, 'title' => 'the title');
self::assertArraysSame($a1, $a2, array('id'));
}
}
私の質問は、おそらく既に利用可能な PHP/PHPUnit 関数を使用して、このタスクを達成するためのより良い方法または簡単な方法はありますか?
編集: PHPUnit のソリューションが必ずしも必要ではないことに注意してください。これを実行できるプレーンな PHP 関数があれば、テストで使用できます。