MWCodebymw.de ↗
PHP

Beträge und Zahlen in PHP formatieren – number_format, sprintf und Intl

1234.5 ist keine Anzeige, sondern ein Wert. Auf der Rechnung soll 1.234,50 € stehen, in der API 1234.50 und im Dateinamen 1234-50. Drei Aufgaben, drei Werkzeuge – und ein Fehler, den fast jeder einmal macht.

Deutsche Zahlen haben Punkt und Komma genau andersherum als englische. Das klingt banal, ist aber die Quelle einer ganzen Fehlerfamilie: falsch angezeigte Rechnungen, Beträge, die beim Import um den Faktor 1000 danebenliegen, Summen mit drei Nachkommastellen.

Der Standardfall: number_format

$betrag = 1234.5;

number_format($betrag, 2, ',', '.');          // 1.234,50
number_format($betrag, 2, ',', '.') . ' €';   // 1.234,50 €
number_format(0.5,   1, ',', '.');            // 0,5
number_format(1234567, 0, ',', '.');          // 1.234.567

Die vier Parameter sind: Wert, Nachkommastellen, Dezimaltrennzeichen, Tausendertrennzeichen. Merksatz für Deutschland: Komma trennt die Stellen, Punkt gruppiert die Tausender.

Wenn es exakt sein muss: sprintf

sprintf('%0.2f', 1234.5);        // 1234.50   – für APIs und CSV
sprintf('%05d', 42);             // 00042     – führende Nullen, z. B. Rechnungsnummern
sprintf('%+.1f %%', 12.345);     // +12.3 %   – mit Vorzeichen
sprintf('RE-%04d-%s', 7, '2026') // RE-0007-2026

%f benutzt immer den Punkt – genau richtig für Schnittstellen, in denen eine Zahl eine Zahl bleiben soll.

Mehrsprachig: die Intl-Erweiterung

$fmt = new NumberFormatter('de_DE', NumberFormatter::CURRENCY);
$fmt->formatCurrency(1234.5, 'EUR');            // 1.234,50 €

$en = new NumberFormatter('en_US', NumberFormatter::CURRENCY);
$en->formatCurrency(1234.5, 'EUR');             // €1,234.50

$prozent = new NumberFormatter('de_DE', NumberFormatter::PERCENT);
$prozent->format(0.1925);                       // 19 %

NumberFormatter kennt die Regeln je Sprache – Position des Währungszeichens, geschütztes Leerzeichen, Gruppierung. Der Haken: Die Erweiterung intl muss auf dem Server aktiv sein. Prüfe das einmal mit extension_loaded('intl') und halte für den Fall der Fälle number_format als Rückfalllösung bereit.

Geld nicht als Fließkommazahl rechnen

0.1 + 0.2 === 0.3;   // false

Das ist kein PHP-Problem, sondern Binärarithmetik. Für Beträge, die addiert und verglichen werden, rechne in Cent als Integer:

$netto  = 19999;                       // 199,99 €
$steuer = (int)round($netto * 0.19);   // 3800
$brutto = $netto + $steuer;            // 23799

echo number_format($brutto / 100, 2, ',', '.') . ' €';   // 237,99 €

Erst ganz am Ende, für die Anzeige, wird geteilt.

Fallstrick

Eingaben zurückzulesen ist die andere Hälfte der Aufgabe: (float)"1.234,50" ergibt 1.234, nicht 1234,50 – PHP hört beim Komma auf. Aus einem Formular kommt der Wert deshalb erst durch eine Normalisierung:

$roh  = '1.234,50';
$wert = (float)str_replace(',', '.', str_replace('.', '', $roh));   // 1234.5

Und speichere Zahlen nie formatiert in der Datenbank. In die Spalte gehört der Wert, die Darstellung entsteht bei der Ausgabe.

Rechnungen, Auswertungen und Exporte, bei denen die Zahlen stimmen, baue ich regelmäßig – schreib mir über bymw.de.

Quellen

#PHP#Formatierung#number_format#Intl#Währung

Du brauchst mehr als ein Snippet?

Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.

Projekt anfragen →