array_merge_recursive_overwrite()
Geschrieben von Gregor Nathanael Meyer um 23:2519 06 2008
Update 30.70.2009: Seit PHP 5.3.0 gibt es endlich die Funktion array_replace_recursive(), die genau das kann, was meine array_merge_recursive_overwrite() macht. Ich habe meine Funktion erweitert, so dass sie lediglich array_replace_recursive() aufruft, wenn diese verfügbar ist. Dies dient nur der Abwärtskompatibilität in bestehenden Projekten und macht keinen Sinn, wenn man neu anfängt. Für einen solchen Fall (hoffentlich der Normalfall) habe ich unter obigem Link einen fertigen Code als Kommentar hinterlassen.
Gestern musste ich mit PHP zwei verschachtelte assoziative Arrays zusammenführen, wobei allerdings bestehende Werte im einen Array durch Werte des anderen überschrieben werden sollten. Leider kommt die PHP-Funktion array_merge_recursive() dafür nicht in Frage, weil sie im Konfliktfall die Werte nicht überschreibt, sondern ein Unterarray baut, in dem beide Werte enthalten sind. Einen Schalter zum Überschreiben gibt es nicht, also musste ich eine eigene Funktion für diesen Zweck bauen. Et voilà, hier ist sie:
/**
* merges two arrays recursively, overwrite existing values in $base with values from $merge
* array_merge_recursive does not overwrite values, it creates a new sub array with both values in it, so we need this function
* since PHP 5.3.0 the built in array_replace_recursive() does the same, so it will be called, if available
*
* @author Gregor Nathanael Meyer <Gregor at der-meyer.de>
* @param array $base base array
* @param array $merge array to be merged into base array
* @param array $merge,... more merge arrays
* @return array merged inputs
*/
function array_merge_recursive_overwrite($base, $merge)
{
// as of PHP 5.3.0 array_replace_recursive() does the work for us
if (function_exists('array_replace_recursive'))
{
return call_user_func_array('array_replace_recursive', func_get_args());
}
function recurse($base, $merge)
{
foreach ($merge as $key => $value)
{
// create new key in $base, if it is empty or not an array
if (!isset($base[$key]) || (isset($base[$key]) && !is_array($base[$key])))
{
$base[$key] = array();
}
// overwrite the value in the base array
if (is_array($value))
{
$value = recurse($base[$key], $value);
}
$base[$key] = $value;
}
return $base;
}
// handle the arguments, merge one by one
$args = func_get_args();
$base = $args[0];
if (!is_array($base))
{
return $base;
}
for ($i = 1; $i < count($args); $i++)
{
if (is_array($args[$i]))
{
$base = recurse($base, $args[$i]);
}
}
return $base;
}
Genau wie ihre Schwester array_merge_recursive() nimmt sie zwei oder mehr Arrays entgegen und gibt diese verbunden zurück. Viel Spaß damit, falls es wer gebrauchen kann.
Nachtrag: Ich hätte auch einfach mal bei Google suchen können, so ziemlich die gleiche Funktion gibt es auch im Horde Framework, allerdings nur für zwei Arrays (also so wie meine innere Funktion). Mist, da hätte ich mir die verhasste Rekursion gar nicht selber ausdenken müssen.
Nachtrag: Die Kommentare in der PHP-Doku bringen auch etliche Varianten dieses Themas. Man sollte sich von unleserlicher Schreibweise nicht abschrecken lassen, auch wenn man schon müde ist. Naja, wenigstens ist meine Lösung nicht total doof.
Kategorien : Web-hinteres-Ende
Trackbacks : Keine Trackbacks »
Short-URL: http://spackblog.de/507

Trackbacks
Keine Trackbacks