Abschnitt 6 · Lektion 4
Gültigkeitsbereich
Wenn du aus JavaScript kommst, ist dieser Punkt der größte Unterschied. Dort sieht eine Funktion alles, was um sie herum steht. In PHP sieht sie nichts davon, und zwar mit Absicht.
Was draußen steht, ist drinnen nicht da
<?php
$name = "Mia";
function begruesse()
{
// $name gibt es hier drinnen nicht:
echo "Hallo ", $name, "!\n";
}
begruesse();
// So gehoert es: der Wert kommt als Parameter herein.
function begruesseRichtig(string $name)
{
echo "Hallo ", $name, "!\n";
}
begruesseRichtig($name); Die erste Ausgabezeile lautet Hallo !, und auf dem Fehlerkanal steht Undefined variable $name.
Das ist die Warning aus Lektion 1.4: php index.php; echo $? meldet eine 0, das Programm hält
sich für erfolgreich, und die Begrüßung ist trotzdem kaputt.
Die Wand selbst kannst du dir im Reiter Debug ansehen. Nach Aufzeichnen steht an der
echo-Zeile in begruesse() nur „Noch keine Variablen”: Von $name ist dort drinnen nichts zu
sehen, obwohl es zwei Zeilen darüber angelegt wurde. An derselben Zeile in begruesseRichtig()
steht name="Mia", weil der Wert als Parameter hereingekommen ist.
Innerhalb einer Funktion gilt nur, was als Parameter hereinkommt oder dort angelegt wird. Der Rest existiert nicht, auch wenn er direkt darüber steht. Das ist der Gültigkeitsbereich, und in PHP ist er hart.
Die zweite Hälfte des Beispiels zeigt die Lösung, und in diesem Kurs ist es die einzige: Alles, was die Funktion braucht, kommt als Parameter herein. Damit sagt die erste Zeile jeder Funktion vollständig, wovon sie abhängt. Genau deshalb kannst du sie irgendwo anders hinkopieren, und genau deshalb lässt sie sich in Abschnitt 17 testen.
Es gäbe noch global $name;. Das kommt in diesem Kurs nicht vor. Damit hängt eine Funktion an
einer Variablen, die irgendwo anders in der Datei entsteht, und du kannst sie weder verschieben noch
zweimal mit verschiedenen Werten aufrufen. Man gewinnt eine Zeile und verliert den ganzen Vorteil.
Die Wand steht in beide Richtungen
<?php
function rechne()
{
$zwischenergebnis = 42;
return $zwischenergebnis * 2;
}
echo rechne(), "\n";
// Und jetzt von aussen danach fragen:
var_dump($zwischenergebnis);
echo "Das Programm laeuft trotzdem weiter.\n"; $zwischenergebnis gibt es nur, solange rechne() läuft. Danach ist es weg, und die Frage danach
liefert null samt Warnung.
Das ist keine Einschränkung, sondern die eigentliche Zusage: Eine Funktion kann dir nichts kaputtmachen, was draußen liegt. Sie nimmt entgegen, was du ihr gibst, und liefert zurück, was sie berechnet hat. Alles dazwischen ist ihre Sache.
Und darum ist der Rückgabewert aus Lektion 6.1 so wichtig. Er ist der einzige reguläre Weg, mit dem etwas aus einer Funktion herauskommt.
Eine Ausnahme, und sie hat einen Namen
<?php
declare(strict_types=1);
function naechsteNummer(): int
{
static $stand = 0;
$stand++;
return $stand;
}
echo naechsteNummer(), "\n";
echo naechsteNummer(), "\n";
echo naechsteNummer(), "\n";
// Zum Vergleich, ohne static:
function ohneStatic(): int
{
$stand = 0;
$stand++;
return $stand;
}
echo ohneStatic(), ohneStatic(), ohneStatic(), "\n"; static vor einer Variablen im Funktionskörper heißt: Diese eine Variable wird nur beim ersten
Aufruf angelegt und behält ihren Wert bis zum Ende des Programms. Die Zählung im Beispiel läuft
deshalb 1, 2, 3, während dieselbe Funktion ohne static dreimal 1 liefert.
Nützlich ist das für einen Zähler, für eine laufende Nummer oder für ein Ergebnis, das teuer zu
berechnen war und beim zweiten Mal nicht noch einmal berechnet werden soll. Sparsam einsetzen:
Eine Funktion mit static liefert bei gleichen Argumenten nicht mehr dasselbe, und damit ist sie
schwerer zu verstehen und schwerer zu prüfen.
Was die Funktion bekommt, ist eine Kopie
<?php
declare(strict_types=1);
function haengeAn(array $liste): array
{
$liste[] = "neu";
return $liste;
}
$obst = ["Apfel"];
// Der Rueckgabewert wird weggeworfen, also passiert nichts:
haengeAn($obst);
echo implode(", ", $obst), "\n";
// So kommt das Ergebnis an:
$erweitert = haengeAn($obst);
echo implode(", ", $erweitert), "\n";
// Mit dem kaufmaennischen Und wird daraus das Original:
function haengeAnDirekt(array &$liste): void
{
$liste[] = "direkt";
}
haengeAnDirekt($obst);
echo implode(", ", $obst), "\n"; Der erste Aufruf im Beispiel sieht aus, als müsste er etwas bewirken, und bewirkt nichts: $obst
enthält danach immer noch nur den Apfel. Die Funktion hat mit einer Kopie gearbeitet und ihr
Ergebnis zurückgegeben, und dieses Ergebnis hat niemand aufgefangen.
Das gilt in PHP für Zahlen, Texte, Wahrheitswerte und, anders als in vielen anderen Sprachen, auch
für Arrays. Ein $liste[] = ... in der Funktion lässt die Liste draußen unberührt.
Mit einem & vor dem Parameter bekommt die Funktion das Original statt einer Kopie. Es steht hier,
damit du es erkennst, wenn du es siehst. Benutz es nicht. Der Aufruf haengeAnDirekt($obst)
sieht harmlos aus und verändert trotzdem eine Variable von außen, und das ist genau die Art von
Fernwirkung, gegen die dieser ganze Abschnitt antritt. Gib etwas zurück und fang es auf.
Zum Mitnehmen
Eine Funktion ist in PHP wirklich abgeschottet. Was draußen in einer Variablen steht, sieht sie nicht, und was sie selbst anlegt, ist danach wieder weg. Das klingt unbequem und ist der Grund, warum sich Funktionen überhaupt wiederverwenden lassen.
Jetzt du
Basis Konto, kostenlosZu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.
Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.
In diesem Kurs läuft dein Code auf einem Server. Dafür hat das Basis Konto 1 Stunde im Monat, mehr Zeit gibt es mit dem Premium Konto.
Was in dieser Lektion steckt
-
Artikel mit 4 Beispielen zum Ausprobieren
Steht hier, ohne Konto lesbar.
-
Aufgabe, dein Code läuft auf einem Server
Öffnet sich mit dem Basis Konto.