number_format($number, $decimals) renvoie le nombre sous forme de chaîne avec un séparateur de milliers et un nombre fixe de décimales : number_format(1234567.891, 2) renvoie "1,234,567.89". Avec un seul argument, elle arrondit à l'entier : number_format(1234567.891) donne "1,234,568".
Les quatre paramètres
number_format(
float $num,
int $decimals = 0,
?string $decimal_separator = ".",
?string $thousands_separator = ","
): string
Le troisième argument est le caractère placé entre la partie entière et les décimales, le quatrième celui placé entre les groupes de trois chiffres. L'un et l'autre peuvent être n'importe quelle chaîne, y compris vide ou un caractère multioctet. Modifiez les séparateurs ci-dessous pour voir chaque style :
Les données de locale (CLDR) utilisent une espace fine insécable (U+202F) pour le français et une espace insécable (U+00A0) pour le russe, afin qu'un nombre ne soit jamais coupé sur deux lignes. En HTML, passez "\u{202F}" ou "\u{00A0}" comme séparateur au lieu d'une espace simple.
Formater un nombre sans séparateur de milliers
Passez '' en quatrième argument. Vous obtenez un nombre simple avec un nombre fixe de décimales, la forme qu'attendent les passerelles de paiement, les exports CSV et les valeurs d'un <input type="number"> :
Pour la dernière ligne, le round() avant le cast compte : 19.9 * 100 est stocké comme 1989.9999999999998, et (int) seul le couperait à 1989.
Comment number_format arrondit
number_format() arrondit la moitié en s'éloignant de zéro, comme round(), donc 0.5 devient 1 et -2.5 devient -3. Elle corrige aussi la minuscule erreur binaire de valeurs comme 2.675, c'est pourquoi elle peut ne pas être d'accord avec sprintf('%.2f') :
2.675 ne peut pas être stocké exactement en binaire ; la valeur stockée est très légèrement inférieure. sprintf() formate cette valeur stockée et obtient 2.67, alors que number_format() et round() la traitent comme le 2.675 que vous avez écrit. Si vous avez besoin d'une règle d'arrondi précise, appelez vous-même round(), floor() ou ceil() d'abord (voir arrondis et calculs) et passez le résultat à number_format().
Formater de l'argent et d'autres devises
number_format() ne sait rien des devises, vous ajoutez donc le symbole vous-même. Placez le signe moins avant le symbole, et souvenez-vous que le yen n'a pas de décimales :
Pour un affichage adapté à la locale, avec la bonne position du symbole dans chaque pays, le NumberFormatter de l'extension intl fait tout le travail :
$fmt = new NumberFormatter('de_DE', NumberFormatter::CURRENCY);
echo $fmt->formatCurrency(1234.5, 'EUR'); // 1.234,50 € (a no-break space before €)
Il demande l'extension intl, qui n'est pas installée partout, donc number_format() avec votre propre symbole est le choix portable.
Le résultat est une chaîne, pas un nombre
C'est le bug le plus courant avec number_format() : formater une valeur puis calculer avec. "1,234.50" n'est pas une chaîne numérique, donc PHP ne lit que le 1 avant la virgule :
<?php
echo number_format(1234.5, 2) + 1;
Warning: A non-numeric value encountered in /home/index.php on line 2
2
Repasser une telle chaîne à number_format() est pire : elle lève TypeError: number_format(): Argument #1 ($num) must be of type int|float, string given. Gardez le nombre brut pour les calculs et ne formatez qu'au moment d'afficher. Si vous recevez une chaîne formatée depuis un formulaire ou un fichier, retirez d'abord les séparateurs :
Pour le remplissage, l'alignement ou un signe plus devant le nombre, utilisez plutôt sprintf() ; elle n'ajoute pas de séparateurs de milliers, mais elle contrôle la largeur et le signe.
Questions fréquentes
Comment formater un nombre avec des séparateurs de milliers en PHP ?
Appelez number_format($n) : number_format(1234567) renvoie "1,234,567". Passez un second argument pour les décimales : number_format(1234567.891, 2) renvoie "1,234,567.89".
Comment utiliser number_format sans virgule ?
Passez une chaîne vide comme séparateur de milliers : number_format(1234.5, 2, '.', '') renvoie "1234.50". C'est la forme qu'attendent en général les API de paiement et les fichiers CSV.
number_format arrondit-elle ou tronque-t-elle ?
Elle arrondit, la moitié en s'éloignant de zéro : number_format(2.5) donne "3", number_format(-2.5) donne "-3" et number_format(2.675, 2) donne "2.68". Pour couper les décimales, utilisez d'abord floor() : number_format(floor(2.679 * 100) / 100, 2) donne "2.67".
Comment formater des nombres à l'européenne (1.234,56) ?
Échangez les séparateurs avec les troisième et quatrième arguments : number_format(1234.56, 2, ',', '.') renvoie "1.234,56". Les styles français et suisse utilisent un espace ou une apostrophe comme quatrième argument.
Pourquoi number_format donne-t-elle un résultat faux quand j'additionne ?
number_format() renvoie une chaîne comme "1,234.50", et PHP ne lit que le 1 avant la virgule quand vous calculez avec. Gardez le nombre pour les calculs et n'appelez number_format() qu'au moment de l'afficher.