Abschnitt 6 · Lektion 3
Vorgaben und benannte Argumente
Bisher hatte jede Funktion genau so viele Argumente, wie sie Parameter hat. Das muss nicht so sein, und meistens ist es auch nicht praktisch: Die häufigste Art, eine Funktion zu benutzen, sollte die kürzeste sein.
Ein Parameter darf einen Vorgabewert haben
<?php
declare(strict_types=1);
function begruesse(string $name, string $gruss = "Hallo", string $zeichen = "!"): string
{
return $gruss . " " . $name . $zeichen;
}
echo begruesse("Mia"), "\n";
echo begruesse("Ben", "Moin"), "\n";
echo begruesse("Tom", "Servus", "."), "\n"; Ein Gleichheitszeichen hinter dem Parameter, dahinter der Wert, der gilt, wenn beim Aufruf nichts
dasteht. Damit ist begruesse("Mia") ein vollständiger Aufruf, obwohl die Funktion drei Parameter
hat.
Der Nutzen liegt nicht im Tippen, sondern im Lesen. Ein Aufruf zeigt nur noch das, was vom
Normalfall abweicht. Wer begruesse("Ben", "Moin") liest, sieht sofort: Hier ist der Gruß anders,
alles andere ist wie immer. Dass die Funktion trotzdem alle drei Werte hat, zeigt der Reiter
Debug: Nach Aufzeichnen steht an der return-Zeile schon beim ersten Aufruf
gruss="Hallo" und zeichen="!", obwohl der Aufruf beides nicht nennt.
Als Vorgabe taugt allerdings nur ein fester Wert: eine Zahl, ein Text, true, null, ein Array aus
festen Werten oder eine Konstante aus Lektion 2.6. Ein Funktionsaufruf geht nicht, denn PHP muss den
Wert schon kennen, bevor irgendetwas läuft.
Beim Aufruf darfst du die Namen dazuschreiben
<?php
declare(strict_types=1);
function speichere(string $text, bool $ueberschreiben = false, bool $sichern = true, bool $melden = false): string
{
return $text . " [" . ($ueberschreiben ? "ueberschreiben" : "-")
. ", " . ($sichern ? "sichern" : "-")
. ", " . ($melden ? "melden" : "-") . "]";
}
// Wer weiss beim Lesen, welches true wozu gehoert?
echo speichere("notiz.txt", true, false, true), "\n";
// Dieselbe Wirkung, aber lesbar:
echo speichere("notiz.txt", ueberschreiben: true, sichern: false, melden: true), "\n";
// Und nur das eine, das vom Ueblichen abweicht:
echo speichere("notiz.txt", melden: true), "\n"; Sieh dir den ersten Aufruf an. speichere("notiz.txt", true, false, true) sagt dir nichts. Du
müsstest zur Funktion hochblättern und nachsehen, welcher Parameter an zweiter Stelle steht und
welcher an dritter.
Seit PHP 8 darfst du beim Aufruf den Parameternamen davorschreiben, mit Doppelpunkt. Die zweite Zeile tut genau dasselbe wie die erste und lässt sich trotzdem lesen, ohne dass man irgendwo nachsieht.
Der dritte Aufruf zeigt den eigentlichen Gewinn: Du kannst mittendrin etwas setzen und den Rest
auf seiner Vorgabe lassen. Ohne benannte Argumente müsstest du $ueberschreiben und $sichern
noch einmal mit ihrem Vorgabewert hinschreiben, nur um an $melden heranzukommen. Genau diese
Zeilen gehen später kaputt, wenn sich eine Vorgabe ändert.
Zwei Dinge dazu. Der Name ist ab jetzt Teil der Funktion, wie ihr Name selbst: Wer einen Parameter
umbenennt, bricht jeden Aufruf, der ihn nennt. Und ein Name, den es nicht gibt, ist ein Abbruch,
kein stilles Ignorieren: php -r 'function f(int $a) {} f(b: 1);'; echo $? im Terminal meldet
Unknown named parameter $b und darunter die 255.
Zwei Regeln, an die PHP dich erinnert
<?php
// Eine Vorgabe vor einem Pflichtparameter:
function rechne(int $summand = 10, int $faktor): int
{
return $summand * $faktor;
}
echo rechne(3, 4), "\n"; Erste Regel: Parameter mit Vorgabe stehen hinten. Sonst könntest du den Vorgabewert gar nicht weglassen, ohne den Platz dahinter mit zu verschieben.
Das Beispiel dreht die Reihenfolge absichtlich um. PHP läuft trotzdem und rechnet 12, meldet aber
auf dem Fehlerkanal Optional parameter $summand declared before required parameter $faktor is implicitly treated as a required parameter. Übersetzt: Die Vorgabe ist wirkungslos, der Parameter
ist in Wahrheit Pflicht. Es ist eine Deprecated-Meldung, also eine Warnung, dass diese Schreibweise
verschwinden wird.
<?php
declare(strict_types=1);
function zeige(int $a, int $b, int $c): string
{
return "$a-$b-$c";
}
// Das geht:
echo zeige(1, b: 2, c: 3), "\n";
// Und das nicht mehr:
echo zeige(a: 1, 2, 3), "\n"; Zweite Regel: Sobald du einen Namen benutzt, müssen alle folgenden Argumente auch Namen haben. Der erste Aufruf im Beispiel ist erlaubt, der zweite nicht.
Beachte die Ausgabe: Sie ist leer. Auch die erste Zeile läuft nicht, denn Cannot use positional argument after named argument ist ein Fehler beim Einlesen der Datei, nicht beim Ausführen. Das ist
dieselbe Sorte wie die falsch platzierte declare-Zeile aus Lektion 6.2.
Wenn du nicht weißt, wie viele es werden
<?php
declare(strict_types=1);
function summiere(int ...$zahlen): int
{
return array_sum($zahlen);
}
echo summiere(1, 2, 3), "\n";
echo summiere(10, 20), "\n";
echo summiere(), "\n";
// Andersherum: eine fertige Liste aufklappen
$liste = [4, 5, 6];
echo summiere(...$liste), "\n"; Drei Punkte vor dem letzten Parameter heißen „und alles Weitere”. In der Funktion liegt das dann als
ganz normale Liste vor, und du kannst mit allem darauf los, was du aus Abschnitt 5 kennst. Kommt gar
nichts, ist die Liste leer, und array_sum liefert 0.
Dieselben drei Punkte funktionieren auch andersherum: summiere(...$liste) klappt eine fertige
Liste zu einzelnen Argumenten auf. Das brauchst du selten, aber wenn, dann sofort.
Zum Mitnehmen
Eine Funktion mit fünf Parametern ist schnell geschrieben und danach unbenutzbar: Niemand weiß beim Aufruf noch, welcher Wert wohin gehört. Zwei Mittel helfen dagegen, und beide kosten dich nichts außer ein paar Zeichen.
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 5 Beispielen zum Ausprobieren
Steht hier, ohne Konto lesbar.
-
Aufgabe, dein Code läuft auf einem Server
Öffnet sich mit dem Basis Konto.