mitmario.dev

Text formatieren

PHP Sandbox 4 Min Lesezeit 4 BeispieleLektion 4 von 7

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

Ein Betrag 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

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

Eine Tabelle, die ausgerichtet steht
<?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

Warum ein Umlaut die Spalte verschiebt
<?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, 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.