<?php
class Tools{
/**
* Recursive version of array_diff_assoc
* Returns everything from $a that is not in $b or the other arguments
*
* @param $a The array to compare from
* @param $b An array to compare against
* @param ... More arrays to compare against
*
* @return An array with everything from $a that not in $b or the others
*/
public static function array_diff_assoc_recursive($a, $b){
// Get all of the "compare against" arrays
// Initial return value
// Loop over the "to" array and compare with the others
foreach($a as $key=>$val){
// We should compare type first
// If it's an array, we recurse, otherwise we just compare with "==="
$args = $aType === 'array' ?
array($val) : true;
// Let's see what we have to compare to
foreach($b as $x){
// If the key doesn't exist or the type is different,
// then it's different, and our work here is done
$ret[$key] = $val;
continue 2;
}
// If we are working with arrays, then we recurse
if($aType === 'array'){
$args[] = $x[$key];
}
// Otherwise we just compare
else{
$args = $args && $val === $x[$key];
}
}
// This is where we call ourselves with all of the arrays we got passed
if($aType === 'array'){
// An empty array means we are equal :-)
$ret[$key] = $comp;
}
}
// If the values don't match, then we found a difference
elseif(!$args){
$ret[$key] = $val;
}
}
return $ret;
}
}
4,
);
4,
);
4,
);
var_dump(Tools
::array_diff_assoc_recursive($a,$b,$c));
PD9waHAKICAgIGNsYXNzIFRvb2xzewogICAgICAgIC8qKgogICAgICAgICAqIFJlY3Vyc2l2ZSB2ZXJzaW9uIG9mIGFycmF5X2RpZmZfYXNzb2MKICAgICAgICAgKiBSZXR1cm5zIGV2ZXJ5dGhpbmcgZnJvbSAkYSB0aGF0IGlzIG5vdCBpbiAkYiBvciB0aGUgb3RoZXIgYXJndW1lbnRzCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gJGEgVGhlIGFycmF5IHRvIGNvbXBhcmUgZnJvbQogICAgICAgICAqIEBwYXJhbSAkYiBBbiBhcnJheSB0byBjb21wYXJlIGFnYWluc3QKICAgICAgICAgKiBAcGFyYW0gLi4uIE1vcmUgYXJyYXlzIHRvIGNvbXBhcmUgYWdhaW5zdAogICAgICAgICAqCiAgICAgICAgICogQHJldHVybiBBbiBhcnJheSB3aXRoIGV2ZXJ5dGhpbmcgZnJvbSAkYSB0aGF0IG5vdCBpbiAkYiBvciB0aGUgb3RoZXJzCiAgICAgICAgICovCiAgICAgICAgcHVibGljIHN0YXRpYyBmdW5jdGlvbiBhcnJheV9kaWZmX2Fzc29jX3JlY3Vyc2l2ZSgkYSwgJGIpewogICAgICAgICAgICAvLyBHZXQgYWxsIG9mIHRoZSAiY29tcGFyZSBhZ2FpbnN0IiBhcnJheXMKICAgICAgICAgICAgJGIgPSBhcnJheV9zbGljZShmdW5jX2dldF9hcmdzKCksIDEpOwogICAgICAgICAgICAvLyBJbml0aWFsIHJldHVybiB2YWx1ZQogICAgICAgICAgICAkcmV0ID0gYXJyYXkoKTsKCiAgICAgICAgICAgIC8vIExvb3Agb3ZlciB0aGUgInRvIiBhcnJheSBhbmQgY29tcGFyZSB3aXRoIHRoZSBvdGhlcnMKICAgICAgICAgICAgZm9yZWFjaCgkYSBhcyAka2V5PT4kdmFsKXsKICAgICAgICAgICAgICAgIC8vIFdlIHNob3VsZCBjb21wYXJlIHR5cGUgZmlyc3QKICAgICAgICAgICAgICAgICRhVHlwZSA9IGdldHR5cGUoJHZhbCk7CiAgICAgICAgICAgICAgICAvLyBJZiBpdCdzIGFuIGFycmF5LCB3ZSByZWN1cnNlLCBvdGhlcndpc2Ugd2UganVzdCBjb21wYXJlIHdpdGggIj09PSIKICAgICAgICAgICAgICAgICRhcmdzID0gJGFUeXBlID09PSAnYXJyYXknID8gYXJyYXkoJHZhbCkgOiB0cnVlOwoKICAgICAgICAgICAgICAgIC8vIExldCdzIHNlZSB3aGF0IHdlIGhhdmUgdG8gY29tcGFyZSB0bwogICAgICAgICAgICAgICAgZm9yZWFjaCgkYiBhcyAkeCl7CiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGtleSBkb2Vzbid0IGV4aXN0IG9yIHRoZSB0eXBlIGlzIGRpZmZlcmVudCwKICAgICAgICAgICAgICAgICAgICAvLyB0aGVuIGl0J3MgZGlmZmVyZW50LCBhbmQgb3VyIHdvcmsgaGVyZSBpcyBkb25lCiAgICAgICAgICAgICAgICAgICAgaWYoIWFycmF5X2tleV9leGlzdHMoJGtleSwgJHgpIHx8ICRhVHlwZSAhPT0gZ2V0dHlwZSgkeFska2V5XSkpewogICAgICAgICAgICAgICAgICAgICAgICAkcmV0WyRrZXldID0gJHZhbDsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgMjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIElmIHdlIGFyZSB3b3JraW5nIHdpdGggYXJyYXlzLCB0aGVuIHdlIHJlY3Vyc2UKICAgICAgICAgICAgICAgICAgICBpZigkYVR5cGUgPT09ICdhcnJheScpewogICAgICAgICAgICAgICAgICAgICAgICAkYXJnc1tdID0gJHhbJGtleV07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vIE90aGVyd2lzZSB3ZSBqdXN0IGNvbXBhcmUKICAgICAgICAgICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgICAgICAgICAkYXJncyA9ICRhcmdzICYmICR2YWwgPT09ICR4WyRrZXldOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHdoZXJlIHdlIGNhbGwgb3Vyc2VsdmVzIHdpdGggYWxsIG9mIHRoZSBhcnJheXMgd2UgZ290IHBhc3NlZAogICAgICAgICAgICAgICAgaWYoJGFUeXBlID09PSAnYXJyYXknKXsKICAgICAgICAgICAgICAgICAgICAkY29tcCA9IGNhbGxfdXNlcl9mdW5jX2FycmF5KGFycmF5KGdldF9jYWxsZWRfY2xhc3MoKSwgJ2FycmF5X2RpZmZfYXNzb2NfcmVjdXJzaXZlJyksICRhcmdzKTsKICAgICAgICAgICAgICAgICAgICAvLyBBbiBlbXB0eSBhcnJheSBtZWFucyB3ZSBhcmUgZXF1YWwgOi0pCiAgICAgICAgICAgICAgICAgICAgaWYoY291bnQoJGNvbXApID4gMCl7CiAgICAgICAgICAgICAgICAgICAgICAgICRyZXRbJGtleV0gPSAkY29tcDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgdmFsdWVzIGRvbid0IG1hdGNoLCB0aGVuIHdlIGZvdW5kIGEgZGlmZmVyZW5jZQogICAgICAgICAgICAgICAgZWxzZWlmKCEkYXJncyl7CiAgICAgICAgICAgICAgICAgICAgJHJldFska2V5XSA9ICR2YWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICRyZXQ7CiAgICAgICAgfQogICAgfQogICAgCiAgICAkYSA9IGFycmF5KAogICAgICAgIGFycmF5KDEsMiwzKSwKICAgICAgICA0LAogICAgICAgIGFycmF5KDUsNikKICAgICk7CiAgICAkYiA9IGFycmF5KAogICAgICAgIGFycmF5KDEsMiwzKSwKICAgICAgICA0LAogICAgICAgIGFycmF5KDUsNikKICAgICk7CiAgICAkYyA9IGFycmF5KAogICAgICAgIGFycmF5KDEsMiksCiAgICAgICAgNCwKICAgICAgICBhcnJheSg1LDYpCiAgICApOwogICAgCiAgICB2YXJfZHVtcChUb29sczo6YXJyYXlfZGlmZl9hc3NvY19yZWN1cnNpdmUoJGEsJGIsJGMpKTs=