Was Referenzen leisten
PHP Referenzen erlauben es, zwei Variablennamen, sich auf den
gleichen Variableninhalt beziehen zu lassen. Das heißt im
folgenden Beispiel, dass sich $a und
$b auf dieselbe Variable beziehen:
Hinweis:
$a und $b sind hier
gleichwertig, und $a ist nicht nur ein
Zeiger auf $b oder umgekehrt, sondern
$a und $b zeigen auf
den selben Inhalt.
Hinweis:
Wenn ein Array mit Referenzen kopiert wird, werden seine Werte nicht
dereferenziert. Dies gilt auch für Array, die per Wert an Funktionen
übergeben werden
Hinweis:
Wenn man eine undefinierte Variable per Referenz zuweist, übergibt oder
zurückgibt, wird sie erstellt.
Beispiel #1 Referenzen mit undefinierten Variablen benutzen
<?php
function foo(&$var) { }
foo($a); // $a wird "erstellt" mit dem Wert null
$b = array();
foo($b['b']);
var_dump(array_key_exists('b', $b)); // bool(true)
$c = new StdClass;
foo($c->d);
var_dump(property_exists($c, 'd')); // bool(true)
?>
Diese Syntax kann auch mit Funktionen, die Referenzen zurückgeben, benutzt
werden und seit PHP 4.0.4 auch in Verbindung mit dem
new-Operator.
Seit PHP 5 referenziert return
new automatisch, also erzeugt
die Verwendung der veralteten Syntax
=& eine
E_STRICT-Warnung.
Hinweis:
Wenn der &-Operator nicht verwendet wird, erzeugt
PHP eine Kopie des Objekts. Wenn nun $this innerhalb
der Klasse verwendet wird, bezieht es sich auf die aktuelle Instanz der
Klasse. Die Zuordnung ohne & erzeugt eine Kopie der
Instanz (d.h. des Objekts) und $this wird sich auf
die Kopie beziehen. In der Regel will man aus Performance- und
Speicherverbrausgründen nur eine einzige Instanz einer Klasse
erzeugen.
Während man den @-Operator benutzen kann, um Fehler
im Konstruktor zu unterdrücken, wenn man ihn als
@new benutzt, funktioniert dies nicht bei der Benutzung
von &new. Dies ist eine Einschränkung der Zend
Engine und resultiert daher in einem Parserfehler.
Warnung
Wenn man einer als global deklarierten Variable eine
Referenz innerhalb einer Funktion zuweist, wird die Referenz nur innerhalb
der Funktion sichtbar sein. Dies kann durch die Verwendung des
$GLOBALS-Arrays vermieden werden.
Beispiel #2 Globale Variablen innerhalb einer Funktion referenzieren
<?php
$var1 = "Beispielvariable";
$var2 = "";
function global_references($use_globals)
{
global $var1, $var2;
if (!$use_globals) {
$var2 =& $var1; // nur innerhalb der Funktion sichtbar
} else {
$GLOBALS["var2"] =& $var1; // auch im globalen Kontext sichtbar
}
}
global_references(false);
echo "var2 wurde auf '$var2' gesetzt\n"; // var2 ist ''
global_references(true);
echo "var2 wurde auf '$var2' gesetzt\n"; // var2 ist 'Beispielvariable'
?>
Man sollte
global $var; als Abkürzung für
$var =& $GLOBALS['var']; sehen. Deswegen ändert die
Zuweisung per Referenz an
$var nur die Referenz
der lokalen Variable.
Hinweis:
Wenn man einer Variable einen Wert per Referenz in einer foreach-Anweisung zuweist,
werden die Referenzen auch geändert.
Beispiel #3 Referenzen und die foreach-Anweisung
<?php
$ref = 0;
$row =& $ref;
foreach (array(1, 2, 3) as $row) {
// do something
}
echo $ref; // 3 - letztes Element des durchlaufenen Arrays
?>
Eine weitere Einsatzmöglichkeit von Referenzen ist die Übergabe
von Parametern an eine Funktion mit pass-by-reference. Hierbei
beziehen sich der lokale Variablenname als auch der Variablenname
der aufrufenden Instanz auf denselben Variableninhalt:
Nach der Ausführung hat
$a den Wert 6, da sich
in der Funktion
foo der Variablenname
$var auf denselben Variableninhalt bezieht wie
$a in der aufrufenden Instanz (hier das Hauptprogramm).
Es gibt auch eine detailliertere Erläuterung der Parameterübergabe
by-reference
Daneben besteht die Möglichkeit aus Funktionen heraus Werte mit
return by-reference
zurückzugeben.