1. Verbinden von Arrays mit Additionsoperator
Eine zunächst naheliegende Methode, zwei Arrays miteinander zu verbinden, ist die Verwendung des Additionsoperators ("+"). Die Syntax lautet dann „$neuesArray = $array1 + $array2;”. Dieses Verfahren funktioniert auch, wenn sich die Schlüssel aller Elemente in $array2 von denen aus $array1 unterscheiden. Wenn jedoch einzelne Schlüssel zwischen den Arrays gleich sind, wird nicht alles miteinander verschmolzen. Bei allen gleichen Schlüsseln wird der Wert aus $array1 beibehalten (je nach Anwendungszweck kann das aber gewünscht sein). Das nächste Beispiel zeigt sowohl den Fall gleicher Schlüssel, als auch den ungleicher Schlüssel:
<?php // Falsches bzw. unerwartetes Ergebnis bei gleichen Schluesseln $arr1 = array('abc'); $arr2 = array('def'); $both1 = $arr1 + $arr2; var_dump($both1); // array(0=>"abc") // Korrektes bzw. erwartetes Ergebnis bei ungleichen Schluesseln $arr1 = array(0 => 'abc'); $arr2 = array(1 => 'def'); $both2 = $arr1 + $arr2; var_dump($both2); // array(0=>"abc", 1=>"def") ?>
array(1) { [0]=> string(3) "abc" } array(2) { [0]=> string(3) "abc" [1]=> string(3) "def" }
2. Verbinden mit array_merge()
In der Regel besser zum Verbinden zweier Arrays ist die Funktion array_merge($arr1, $arr2, ...). Dieser können beliebig viele Arrays als Parameter übergeben werden. Die Rückgabe ist ein Array, welches alle Werte aus den übergebenen Arrays enthält.
<?php $arr1 = array('abc'); $arr2 = array('def'); $both = array_merge($arr1, $arr2); var_dump($both); ?>
array(2) { [0]=> string(3) "abc" [1]=> string(3) "def" }
Bei Anwendung von array_merge() gehen die bisherigen Schlüssel in den Arrays verloren. Die Reihenfolge im Rückgabearray entspricht der Reihenfolge der Elemente in den übergebenen Arrays.
<?php $arr1 = array(999 => 'abc'); // wird zu 0 => "abc" $arr2 = array(222 => 'def'); // wird zu 1 => "def" $both = array_merge($arr1, $arr2); var_dump($both); ?>
array(2) { [0]=> string(3) "abc" [1]=> string(3) "def" }
Mit array_merge können auch mehr als zwei Arrays verschmolzen werden:
<?php $arr1 = array('abc'); $arr2 = array('def'); $arr3 = array('ghi'); $arr4 = array('jkl'); $all = array_merge($arr1, $arr2, $arr3, $arr4); var_dump($all); ?>
array(4) { [0]=> string(3) "abc" [1]=> string(3) "def" [2]=> string(3) "ghi" [3]=> string(3) "jkl" }
3. array_merge() bei zwei Arrays mit gleichen Schlüssel
array_merge() kann auf zwei Arrays mit gleichen Schlüsseln angewendet werden, sofern die Schlüssel Integer-Werte sind. Ist das der Fall, dann werden alle Werte in das neue Array übernommen. Sie erhalten neue Schlüssel, welche von 0 an aufsteigend durchnummeriert sind (0, 1, 2, 3, ...).
<?php $arr1 = array(100=>'a', 101=>'b', 777=>'c'); $arr2 = array(100=>'d', 101=>'e', 999=>'f'); $both1 = array_merge($arr1, $arr2); $both2 = array_merge($arr2, $arr1); var_dump($both1); var_dump($both2); ?>
array(6) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> string(1) "c" [3]=> string(1) "d" [4]=> string(1) "e" [5]=> string(1) "f" } array(6) { [0]=> string(1) "d" [1]=> string(1) "e" [2]=> string(1) "f" [3]=> string(1) "a" [4]=> string(1) "b" [5]=> string(1) "c" }
Überschneiden sich String-Schlüssel in den beiden Arrays, dann kommt es zu Problemen. Ist ein bestimmter String-Schlüssel sowohl im ersten als auch im zweiten Array bereits belegt, dann wird der Wert aus dem ersten Array übernommen. Der Wert aus dem zweiten Array verfällt.
<?php $arr1 = array('key1'=>'a', 'key2'=>'b', 'key3'=>'c'); $arr2 = array('key1'=>'d', 'key2'=>'e', 'key3'=>'f'); $both1 = array_merge($arr1, $arr2); $both2 = array_merge($arr2, $arr1); var_dump($both1); var_dump($both2); ?>
array(3) { ["key1"]=> string(1) "d" ["key2"]=> string(1) "e" ["key3"]=> string(1) "f" } array(3) { ["key1"]=> string(1) "a" ["key2"]=> string(1) "b" ["key3"]=> string(1) "c" }
4. Eigenes array_merge() mit/ohne Überschreiben von belegten Schlüsseln
Nachfolgend wird eine Funktion definiert, die zwei Arrays $arr1 und $arr2 miteinander zu einem neuen Array verschmelzt. Die Funktion erwartet als dritten Parameter ($overwrite) eine Angabe, ob bereits in $arr1 existierende Schlüssel überschrieben werden dürfen, wenn diese auch in $arr2 vorhanden sind. Ist der Parameter (bool)true, dann werden sie überschrieben, sonst nicht. Das Vorgehen der Schleife ist vergleichsweise einfach: Sie iteriert per foreach über alle Elemente in $arr2 und prüft für jedes einzelne, ob der Schlüssel schon in $arr1 belegt ist. Falls nein, wird das Element direkt zu $arr1 hinzugefügt. Falls ja und gleichzeitig der dritte Parameter ($overwrite) auf (bool)true gesetzt ist, wird der Wert in $arr1 durch den in $arr2 ersetzt. Am Ende wird nur noch das Array $arr1 zurückgegeben, welches durch die foreach-Schleife verändert wurde.
<?php function myMerge($arr1, $arr2, $overwrite) { foreach($arr2 as $key=>$val) { if (!isset($arr1[$key]) || $overwrite===true) { $arr1[$key] = $val; } } return $arr1; } $arr1 = array('key1'=>'a', 'key2'=>'b', 100=>'c'); $arr2 = array('key1'=>'d', 'key2'=>'e', 200=>'f'); var_dump(myMerge($arr1, $arr2, false)); var_dump(myMerge($arr1, $arr2, true)); ?>
array(4) { ["key1"]=> string(1) "a" ["key2"]=> string(1) "b" [100]=> string(1) "c" [200]=> string(1) "f" } array(4) { ["key1"]=> string(1) "d" ["key2"]=> string(1) "e" [100]=> string(1) "c" [200]=> string(1) "f" }
5. Eigenes array_merge() mit while-Schleife
Die nachfolgende Funktion verbindet wieder zwei Arrays $arr1 und $arr2, erledigt das diesmal aber über eine while-Schleife. Innerhalb der while-Schleife werden die Funktionen array_shift($arr) und array_push($arr, $value) aufgerufen. array_shift($arr) entfernt den ersten Wert des Arrays $arr und gibt ihn zurück. (Das Array wird an die Funktion automatisch per Referenz übergeben, daher bleibt dieses auch nach Aufruf der Funktion verändert.) An array_push($arr, $value) wiederum wird der von array_shift() gelieferte Wert übergeben. array_push() fügt diesen dann am Ende von $arr hinzu. Der von array_shift() gelieferte Wert wird in der Variablen $el gespeichert. Wenn das Array $arr2 (auf dieses wird array_shift() angewendet) leer ist, dann ist $el NULL und die while-Schleife wird beendet (da NULL wie false interpretiert wird). So läuft die Schleife von selbst so lange, bis $arr2 leer ist und alle Werte an $arr1 übergeben wurden.
Diese Funktion fügt alle Werte von $arr2 zu $arr1 hinzu, unabhängig von deren Schlüsseln. Überschrieben wird kein Element aus $arr1. Während die Schlüssel aus $arr1 beibehalten werden, werden die Elemente aus $arr2 neu durchnummeriert. Der gleiche Effekt kann auch durch Anwendung von array_merge($arr1, array_values($arr2)) erreicht werden.
<?php function myMergeValues($arr1, $arr2) { // $el ist NULL wenn $arr2 leer ist, die Schleife bricht dann ab while ($el = array_shift($arr2)) { array_push($arr1, $el); } return $arr1; } $arr1 = array('key1'=>'a', 'key2'=>'b', 100=>'c'); $arr2 = array('key1'=>'d', 'key2'=>'e', 200=>'f'); var_dump(myMergeValues($arr1, $arr2)); ?>
array(6) { ["key1"]=> string(1) "a" ["key2"]=> string(1) "b" [100]=> string(1) "c" [101]=> string(1) "d" [102]=> string(1) "e" [103]=> string(1) "f" }
6. Mehrdimensionale Arrays mit array_merge_recursive() verbinden
Neben array_merge() wird von PHP auch array_merge_recursive($arr1, $arr2) zur Verfügung gestellt. Existiert in $arr1 und $arr2 jeweils ein Array mit Namen X, dann werden durch array_merge_recursive() alle Werte des Arrays X aus $arr2 zum selbigen Array in $arr1 hinzugefügt. Oder anders ausgedrückt: Die Funktion verschmelzt alle gleich benannten Arrays in $arr1 und $arr2.
<?php // "first", "second" und "X"=>"Y" werden verschmolzen // "sub" wird nicht verschmolzen, da der "Eltern-Key" einmal "bla1" und einmal "bla2" ist $arr1 = array('first' => array('a', 'b'), 'second' => array('c', 'd'), 'bla1'=>array('sub' => array()), 'X'=>array('Y'=>array()), 888); $arr2 = array('first' => array('e', 'f'), 'second' => array('g', 'h'), 'bla2'=>array('sub' => 1), 'X'=>array('Y'=>array(1)), 999); echo "------\narray_merge_recursive():\n------\n\n"; print_r(array_merge_recursive($arr1, $arr2)); // zum Vergleich array_merge echo "\n\n\n------\narray_merge():\n------\n\n"; print_r(array_merge($arr1, $arr2)); ?>
------ array_merge_recursive(): ------ Array ( [first] => Array ( [0] => a [1] => b [2] => e [3] => f ) [second] => Array ( [0] => c [1] => d [2] => g [3] => h ) [bla1] => Array ( [sub] => Array ( ) ) [X] => Array ( [Y] => Array ( [0] => 1 ) ) [0] => 888 [bla2] => Array ( [sub] => 1 ) [1] => 999 ) ------ array_merge(): ------ Array ( [first] => Array ( [0] => e [1] => f ) [second] => Array ( [0] => g [1] => h ) [bla1] => Array ( [sub] => Array ( ) ) [X] => Array ( [Y] => Array ( [0] => 1 ) ) [0] => 888 [bla2] => Array ( [sub] => 1 ) [1] => 999 )
7. Werte von mehrdimensionalen Arrays verbinden
Will man von zwei mehrdimensionalen Arrays nur die Werte extrahieren und zu einem neuen, eindimensionalen Array verbinden, dann kann die nachfolgende Funktion „myMergeRecursive($arr1, $arr2)” dafür verwendet werden. Diese erwartet die beiden mehrdimensionalen Arrays und gibt das eindimensionale Ergebnisarray zurück.
Aufbau der Funktion: Die Funktion beginnt damit, über „$arr1[] = $arr2” das zweite Array zum Ersten hinzuzufügen. So muss nur noch über ein statt zwei mehrdimensionale Arrays iteriert werden. Anschließend wird die Funktion array_walk_recursive($arr, $callback) verwendet, um die Callback-Funktion $callback auf jeden einzelnen Wert in $arr1 anzuwenden. Diese Callback-Funktion macht hier nichts anderes, als den an ihr übergebenen Wert zu einem neuen Array $out hinzuzufügen. So wird Stück für Stück $out um die Werte in $arr1 ergänzt (und $arr1 enthält wiederum $arr2, sodass auch alle Werte von $arr2 zu $out hinzugefügt werden). Am Ende muss $out nur noch zurückgegeben werden.
<?php function myMergeRecursive($arr1, $arr2) { $arr1[] = $arr2; $out = array(); array_walk_recursive($arr1, function($val) use (&$out) { $out[] = $val; }); return $out; } $arr1 = array(array('a', 'b'), array('c', 'd')); $arr2 = array(array('e', 'f'), array('g', 'h')); var_dump(myMergeRecursive($arr1, $arr2)); ?>
array(8) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> string(1) "c" [3]=> string(1) "d" [4]=> string(1) "e" [5]=> string(1) "f" [6]=> string(1) "g" [7]=> string(1) "h" }