Abschnitt 3 · Lektion 4
Text formatieren
Bis hierher hast du Werte ausgegeben, wie sie eben herauskamen. In $betrag steht 1234.5, also
erscheint 1234.5. Auf einer Rechnung will das niemand lesen. Diese Lektion handelt davon, wie aus
einem Wert eine Zeile wird, die ein Mensch ansehen kann.
Beträge in deutscher Schreibweise
<?php
$betrag = 1234.5;
echo "Ohne alles: ", $betrag, "\n";
echo "Zwei Nachkommastellen: ", number_format($betrag, 2), "\n";
echo "Deutsche Schreibweise: ", number_format($betrag, 2, ",", "."), "\n";
echo "Ganz ohne Nachkomma: ", number_format($betrag, 0, ",", "."), "\n"; number_format kennst du seit Lektion 2.3, dort mit zwei Argumenten: dem Wert und der Zahl der
Nachkommastellen. Was du dabei bekommen hast, war die englische Schreibweise, und das fällt erst
auf, sobald die Zahl größer als tausend wird. number_format(1234.5, 2) ergibt 1,234.50, mit Komma
als Tausendertrenner und Punkt vor den Cent.
In Deutschland ist beides vertauscht. Deshalb nimmt die Funktion zwei weitere Argumente: erst das
Zeichen vor den Nachkommastellen, dann das für die Tausendertrennung. number_format($betrag, 2, ",", ".") ergibt 1.234,50, und das ist die Form, die du in diesem Kurs überall nimmst.
Achte auf die letzte Zeile im Beispiel. Mit 0 Nachkommastellen kommt 1.235 heraus, nicht 1.234:
number_format rundet, es schneidet nicht ab. Bei Beträgen ist das richtig so, aber wenn du eine
Zahl nur kürzer anzeigen willst, solltest du es wissen.
Platzhalter statt Zusammenkleben
<?php
$name = "Mia";
$anzahl = 3;
$preis = 4.5;
printf("%s hat %d Stueck gekauft.\n", $name, $anzahl);
printf("Einzelpreis: %.2f Euro\n", $preis);
printf("Bestellnummer: %05d\n", 42);
printf("Rabatt: 10%%\n");
$zeile = sprintf("%s: %.2f", $name, $preis);
echo $zeile, "\n"; In der letzten Lektion hast du Sätze mit Punkten zusammengesetzt. Sobald mehr als zwei Werte
hineingehören, wird das unübersichtlich. Die Alternative heißt printf: Du schreibst den Satz
einmal am Stück, mit Platzhaltern an den Stellen, an denen Werte hingehören, und gibst die Werte
danach mit.
Vier Platzhalter brauchst du in diesem Kurs:
%s steht für Text, und alles, was kein Text ist, wird dafür zu einem gemacht. %d steht für eine
ganze Zahl. %.2f steht für eine gebrochene Zahl mit zwei Nachkommastellen, was auf den ersten Blick
wie number_format klingt, aber ohne Tausendertrenner arbeitet und immer den Punkt nimmt. Für Beträge
bleibt number_format deshalb die bessere Wahl. Und %05d heißt „ganze Zahl, mindestens fünf
Stellen, vorne mit Nullen aufgefüllt”, also genau die führenden Nullen, die in Lektion 3.1 gefehlt
haben.
Ein Prozentzeichen im Text schreibst du als %%, sonst hält PHP es für den Anfang eines Platzhalters.
Die letzte Zeile zeigt den Zwilling: sprintf tut dasselbe wie printf, gibt das Ergebnis aber
zurück, statt es auszugeben. Das eine schreibt, das andere liefert. Diese Unterscheidung begegnet dir
in PHP noch öfter.
Spalten, die untereinander stehen
<?php
printf("%-14s%12s EUR\n", "Schreibtisch", number_format(899.9, 2, ",", "."));
printf("%-14s%12s EUR\n", "Regal", number_format(334.6, 2, ",", "."));
printf("%-14s%12s EUR\n", "Summe", number_format(899.9 + 334.6, 2, ",", ".")); Eine Zahl in einem Platzhalter darf auch sagen, wie breit die Spalte sein soll. %12s heißt
„mindestens zwölf Zeichen breit, der Text steht rechts”, und ein Minuszeichen dreht das um: %-14s
schiebt den Text nach links und füllt rechts auf.
Damit steht eine Tabelle auf der Kommandozeile in drei Zeilen Code. Namen links, Beträge rechts, und weil die Beträge rechtsbündig stehen, liegen Komma und Cent-Stellen genau untereinander. Auf einer Zahlenkolonne ist das der Unterschied zwischen lesbar und nicht lesbar.
Dasselbe geht mit str_pad($text, 14), das rechts auffüllt, und mit STR_PAD_LEFT als drittem
Argument andersherum. Nimm, was dir besser gefällt.
Und jetzt die Falle
<?php
printf("[%-14s] fertig\n", "Schreibtisch");
printf("[%-14s] fertig\n", "Buerostuhl");
printf("[%-14s] fertig\n", "Bürostuhl");
echo "\n";
echo "Bürostuhl hat ", mb_strlen("Bürostuhl"), " Zeichen,\n";
echo "aber ", strlen("Bürostuhl"), " Bytes.\n"; Sieh dir im Beispiel an, wo die schließende Klammer steht. In den ersten beiden Zeilen an derselben Stelle, in der dritten eine Position weiter links.
Der Grund steht in Lektion 2.2, und hier zeigt er zum ersten Mal, was er anrichtet: %-14s und
str_pad zählen Bytes, nicht Zeichen. Bürostuhl hat neun Zeichen, belegt aber zehn Bytes, weil
das ü zwei davon braucht. PHP füllt also auf vierzehn Bytes auf, und sichtbar sind dann nur
dreizehn Zeichen.
Bei einer Namensliste mit Umlauten franst deine schöne Tabelle deshalb auf der rechten Seite aus, und
zwar unterschiedlich weit, je nachdem wie viele Umlaute in der Zeile stecken. Es gibt seit PHP 8.3
ein mb_str_pad, das richtig zählt. Der Kurs setzt 8.2 voraus, weil das auf den meisten
Hosting-Paketen die ältere Grenze ist, deshalb kommt es hier nicht in einer Lösung vor. Die Maschine
im Kurs ist neuer (php --version im Terminal sagt es dir), du kannst es also ausprobieren:
php -r 'echo "[", mb_str_pad("Bürostuhl", 14), "]", PHP_EOL;' setzt die Klammer dorthin, wo sie
bei den beiden Zeilen ohne Umlaut steht.
Womit du praktisch leben musst: Ausgerichtete Spalten und Umlaute vertragen sich auf der Kommandozeile schlecht. Im Browser stellt sich die Frage nicht mehr, dort macht eine Tabelle das Ausrichten von selbst. Die Aufgabe zu dieser Lektion nimmt deshalb Posten ohne Umlaute, und jetzt weißt du, warum.
Zum Mitnehmen
PHPs Vorgabe für Beträge ist die englische: Komma als Tausendertrenner, Punkt vor den Cent. In Deutschland ist es genau andersherum, und beide Zeichen stehen als Argument bereit.
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.