Rolf B: zusammenführen zwei Variablennamen

Beitrag lesen

Hallo robertroth,

danke für die Mahnung. Diese Spezialität der Speicherverwaltung in PHP kann man nicht oft genug wiederholen.

Solange man nichts anderes verlangt, übergibt PHP alles per Wert. Sowas ist klassischerweise ein bäh für die Performance, weil wie wild kopiert wird.

Die Magie der schnellen Ausführung in PHP besteht darin, dass PHP die Kopie solange hinauszögert, bis ein Schreibzugriff erfolgt.

$foo = [
   [ 11, 12, 13, 14 ],
   [ 21, 22, 23, 24 ]
];

$x = $foo[0];   // <-- $foo[0] und $foo[1] werd NOCH nicht kopiert.
$y = $foo[1];   //      $x und $foo[0] zeigen auf den gleichen Speicher.
                //      $y und $foo[1] ebenso.

D.h. beiden Teilarrays werden jetzt doppelt genutzt. Es sind "Geheime Referenzen" entstanden. PHP zählt das mit (reference counting). Schreibzugriffe lösen die Geheimreferenzen auf und erstellen Kopien:

$x[2] = 4711;   // <-- kopiert $foo[0] und $x zeigt auf die Kopie.
$foo[1] = 815;  // <-- kopiert $foo[1]. $y behält den alten Wert, und
                //     $foo[1] bekommt die Kopie

Jetzt haben wir vier Teilarrays und keine Geheim-Referenzen mehr. Alle werden nur noch einmal genutzt. Und das bedeutet, dass weitere Schreibzugriffe keine Kopie mehr herstellen.

$x[3] = 1234;   // Keine Kopie!

Ich glaube, diesen Aufwand mit copy-on-demand treibt keine andere Programmiersprache. Anderswo bleibt das dem Programmierer überlassen.

Der Adressoperator ändert das Verhalten! An Stelle einer geheimen Referenz entsteht eine öffentliche, und die darf auch öffentlich weiterexistieren:

$foo = [ 1,2,3,4 ];
$x = &$foo;         // Hier entsteht eine offizielle Referenz

$x[2] = 123;        // Jetzt wird NICHT kopiert!
print_r($foo);      // Änderung ist in $foo sichtbar

Rolf

--
sumpsi - posui - obstruxi