Kopieren eines Arrays in PHP: Einfache Zuweisung oder Klon?

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Tiefes Kopieren eines Arrays in PHP: Mythen und Realität

\n\n

Stellen Sie sich vor: Sie schreiben ein Skript, das Daten aus einer Datenbank verarbeitet. Sie erhalten ein Array mit Benutzern, arbeiten damit und stellen plötzlich fest, dass die ursprünglichen Daten geändert wurden. Kommt Ihnen das bekannt vor? Wenn Sie mit PHP arbeiten, kann dieses Problem selbst erfahrene Entwickler überraschen.

\n\n

Die Frage „Is there a function to make a copy of a PHP array to another?“ auf Stack Overflow hat zehntausende Aufrufe. Und das ist kein Zufall. Auf den ersten Blick scheint das Kopieren von Arrays in PHP eine triviale Aufgabe zu sein. Aber der Teufel steckt, wie immer, im Detail.

\n\n

In diesem Artikel analysieren wir alle möglichen Methoden zum Kopieren eines Arrays in PHP: von der einfachen Zuweisung bis zur Arbeit mit mehrdimensionalen Strukturen. Sie erfahren, wann PHP eine echte Kopie erstellt und wann nur eine Referenz auf die Daten. Los geht's!

\n\n

Direkte Zuweisung: Die erste Überraschung

\n\n

Der intuitivste Weg ist, ein Array einfach einer anderen Variable zuzuweisen:

\n\n
$original = ['apple', 'banana', 'cherry'];\n$copy = $original;\n$copy[0] = 'mango';\n\nprint_r($original);\n// Array ( [0] => apple [1] => banana [2] => cherry )\nprint_r($copy);\n// Array ( [0] => mango [1] => banana [2] => cherry )
\n\n

Überraschenderweise funktioniert das! In PHP sind Arrays value types (Wertetypen), keine Referenztypen. Wenn Sie ein Array einer anderen Variable zuweisen, erstellt PHP eine flache Kopie (shallow copy) mit verzögerter Kopie (copy-on-write).

\n\n

Einfach ausgedrückt: Solange Sie keines der Arrays ändern, zeigen sie auf dieselben Daten im Speicher. Sobald Sie versuchen, ein Element in einer der Variablen zu ändern, weist PHP neuen Speicher zu und kopiert die Daten. Das ist sehr effizient und erfordert keine zusätzlichen Aktionen.

\n\n

Fazit: Für einfache eindimensionale Arrays ist die direkte Zuweisung eine vollwertige Kopie.

\n\n

Fallstrick: Objekte innerhalb des Arrays

\n\n

Stellen Sie sich nun vor, dass sich im Array Objekte befinden:

\n\n
class User {\n    public $name;\n    public function __construct($name) {\n        $this->name = $name;\n    }\n}\n\n$original = [new User('Alice'), new User('Bob')];\n$copy = $original;\n$copy[0]->name = 'Charlie';\n\nprint_r($original[0]->name); // Charlie
\n\n

Da haben wir die Überraschung! Die flache Kopie hat die Referenz auf das Objekt kopiert, nicht das Objekt selbst. Wenn Sie das Objekt in der Kopie ändern, ändern Sie es auch im Original. Für Objekte ist ein anderer Ansatz erforderlich.

\n\n

Die Funktion array_merge(): Nicht offensichtliche Nuancen

\n\n

Oft wird empfohlen, array_merge() zum Kopieren eines Arrays zu verwenden:

\n\n
$original = [1, 2, 3];\n$copy = array_merge([], $original);\n$copy[0] = 100;\n\nprint_r($original); // [1, 2, 3]
\n\n

Ja, das funktioniert. Aber es gibt eine wichtige Nuance: array_merge() setzt numerische Schlüssel zurück und nummeriert sie neu ab Null. Wenn Ihre Schlüssel Zeichenketten sind, ist alles in Ordnung. Wenn sie numerisch sind, müssen Sie mit Überraschungen rechnen:

\n\n
$original = ['a' => 1, 2 => 'two', 5 => 'five'];\n$copy = array_merge([], $original);\n\nprint_r($copy);\n// Array ( [a] => 1 [0] => two [1] => five )
\n\n

Sehen Sie? Die Schlüssel 2 und 5 wurden zu 0 und 1. Dies kann die Logik zerstören, wenn die Reihenfolge der Schlüssel wichtig ist.

\n\n

Fazit: array_merge() eignet sich nur zum Kopieren von Arrays mit Zeichenkettenschlüsseln oder wenn eine Neuindizierung nicht schlimm ist.

\n\n

Kopieren mit einer Schleife: Manuelle Steuerung

\n\n

Der zuverlässigste, aber auch der ausführlichste Weg ist, das Array mit einer Schleife zu durchlaufen:

\n\n
$original = ['x' => 10, 'y' => 20];\n$copy = [];\n\nforeach ($original as $key => $value) {\n    $copy[$key] = $value;\n}\n\n$copy['x'] = 100;\nprint_r($original['x']); // 10
\n\n

Für einfache Arrays ist das überflüssig. Aber wenn Sie eine tiefe Kopie (deep copy) erstellen müssen, dann ohne Rekurs

Blogs

Buchempfehlungen