mitmario.dev

Eine eigene Funktion

PHP Sandbox 3 Min Lesezeit 4 BeispieleLektion 1 von 8

Funktionen kennst du längst, du hast sie nur nicht selbst gebaut. count(), number_format(), array_filter(): Jedes Mal gibst du etwas hinein, und etwas kommt zurück. In dieser Lektion baust du dir solche Bausteine selbst.

Ein Name für einen Rechenweg

Dreimal derselbe Weg, einmal geschrieben
<?php

// Von Hand, dreimal fast dasselbe:
echo number_format(20 * 1.19, 2), "\n";
echo number_format(40 * 1.19, 2), "\n";
echo number_format(60 * 1.19, 2), "\n";

// Mit einer Funktion steht der Weg einmal da:
function brutto($netto)
{
    return $netto * 1.19;
}

echo number_format(brutto(20), 2), "\n";
echo number_format(brutto(40), 2), "\n";
echo number_format(brutto(60), 2), "\n";

Das Wort function, ein Name, die Klammern mit den Parametern, und dazwischen der Körper. Ein Parameter ist eine Variable, die es nur innerhalb der Funktion gibt und die beim Aufruf ihren Wert bekommt. return beendet die Funktion sofort und schickt einen Wert an die Stelle zurück, an der sie aufgerufen wurde.

Beide Hälften des Beispiels geben dasselbe aus. Der Unterschied liegt woanders: Oben steht der Steuersatz dreimal da. Wird aus 19 Prozent irgendwann 20, musst du drei Zeilen finden und drei Zeilen ändern, und wenn du eine übersiehst, merkt das niemand. Unten steht er einmal.

Genau das ist der Grund für Funktionen, und er hat nichts mit Eleganz zu tun. Eine Sache gehört an genau eine Stelle. Denselben Gedanken hattest du schon bei den Konstanten in Lektion 2.6, dort ging es um einen Wert, hier geht es um einen Weg.

Zurückgeben ist etwas anderes als ausgeben

Sagen oder zurückgeben
<?php

function sagHallo($name)
{
    echo "Hallo $name!\n";
}

function baueHallo($name)
{
    return "Hallo $name!";
}

$a = sagHallo("Mia");
var_dump($a);

$b = baueHallo("Ben");
var_dump($b);

// Nur das Zurueckgegebene laesst sich weiterverwenden:
echo mb_strtoupper($b), "\n";

Beide Funktionen im Beispiel machen auf den ersten Blick dasselbe. Sieh dir aber an, was in $a und in $b landet.

sagHallo() schreibt den Text direkt auf die Ausgabe und gibt nichts zurück. Eine Funktion ohne return liefert immer null, und ein return; ohne Wert ebenso. In $a steht deshalb NULL, und damit kannst du nichts mehr anfangen: Der Satz ist schon draußen.

baueHallo() gibt den Text zurück. In $b liegt eine echte Zeichenkette, die du weiterreichen, verändern oder erst später ausgeben kannst. Die letzte Zeile macht genau das.

Daraus die Faustregel, die dich den ganzen Kurs begleitet: Eine Funktion, die etwas ausgibt, ist meistens die schlechtere. Sie legt fest, wann und wo der Text erscheint, und sie ist nicht prüfbar. Ab Abschnitt 10 baust du Seiten, bei denen die Reihenfolge der Ausgabe wirklich zählt, und in Abschnitt 17 schreibst du Tests, die einen Rückgabewert vergleichen. Eine Funktion, die nur redet, hat dort nichts zu bieten.

Warum man diesen Unterschied sehen kann

Aus drei Rückgaben wird eine Liste
<?php

function listenEintrag($name, $cent)
{
    return "<li>" . $name . ": " . number_format($cent / 100, 2, ",", ".") . " Euro</li>";
}

$waren = ["Kabel" => 990, "Maus" => 2490, "Tastatur" => 4365];

$eintraege = [];
foreach ($waren as $name => $cent) {
    $eintraege[] = listenEintrag($name, $cent);
}

echo "<ul>\n";
echo implode("\n", $eintraege), "\n";
echo "</ul>\n";

Hier läuft ein Server, als einzigem Beispiel in diesem Abschnitt, und im Reiter Browser steht eine Seite. Der Grund ist derselbe wie in Lektion 5.3: Der Punkt lässt sich schlecht beschreiben, solange man ihn nicht sieht.

listenEintrag() gibt ein <li> zurück, statt es auszugeben. Deshalb kannst du die drei Rückgaben erst einsammeln und danach zwischen <ul> und </ul> setzen. Mit einem echo in der Funktion ginge das nicht: Die drei Einträge wären längst draußen, bevor der Listenanfang geschrieben wird, und im Browser stünde kaputtes Markup.

Sieh dir beide Stellen an. Im Browser steht die Liste mit Aufzählungspunkten. Tipp dann php index.php im Terminal: Da steht dieselbe Ausgabe noch einmal, aber als Zeichen, spitze Klammer, u, l. Derselbe Code, zweimal angesehen.

In den anderen sechs Lektionen dieses Abschnitts läuft kein Server, und das ist kein Ausfall. Dort geht es um Typen, Argumente, Sichtbarkeit und zum Schluss um Klassen, und dafür ist die Ausgabe im Terminal die richtige Ansicht.

Zwei Regeln für den Namen

Der Aufruf ist unempfindlich, der Variablenname nicht
<?php

function brutto($netto)
{
    return $netto * 1.19;
}

// Alle drei rufen dieselbe Funktion auf:
echo brutto(100), "\n";
echo Brutto(100), "\n";
echo BRUTTO(100), "\n";

// Bei Variablen ist das anders:
$preis = 100;
$Preis = 200;
echo $preis, " und ", $Preis, "\n";

Erstens: Nimm ein Verb. Eine Funktion tut etwas, ihr Name sagt was. brutto() geht gerade noch durch, weil das Ergebnis so heißt; preisberechnung() ist schon ein Bericht statt einer Anweisung. Gut sind berechneBrutto(), baueHallo(), findeKunde().

Zweitens, und das ist die Falle: Beim Aufruf ist PHP die Schreibweise egal. BRUTTO(100) findet dieselbe Funktion wie brutto(100), ganz ohne Warnung. Bei Variablen ist es genau umgekehrt, $preis und $Preis sind zwei verschiedene Behälter, wie du schon in Lektion 2.1 gesehen hast.

Verlass dich trotzdem nie darauf. Schreib den Namen überall gleich, so wie du ihn definiert hast. Sonst suchst du eine Funktion irgendwann per Textsuche und findest die Hälfte ihrer Aufrufe nicht.

Zum Mitnehmen

Bisher stand jede Zeile genau einmal da und lief genau einmal. Eine Funktion dreht das um: Du schreibst einen Rechenweg einmal auf, gibst ihm einen Namen und benutzt ihn danach so oft du willst. Ab hier wird dein Code wiederverwendbar, und ab hier wird er auch prüfbar.

Jetzt du

Basis Konto, kostenlos

Zu 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.