number_format($number, $decimals) retorna o número como string com um separador de milhar e um número fixo de casas decimais: number_format(1234567.891, 2) retorna "1,234,567.89". Com um argumento, ele arredonda para um número inteiro: number_format(1234567.891) é "1,234,568".
Os quatro parâmetros
number_format(
float $num,
int $decimals = 0,
?string $decimal_separator = ".",
?string $thousands_separator = ","
): string
O terceiro argumento é o caractere entre a parte inteira e as casas decimais, o quarto o caractere entre os grupos de três dígitos. Qualquer um deles pode ser qualquer string, inclusive vazia ou um caractere multibyte. Edite os separadores abaixo para ver cada estilo:
Os dados de locale (CLDR) usam um espaço estreito não separável (U+202F) para o francês e um espaço não separável (U+00A0) para o russo, para que um número nunca seja quebrado em duas linhas. No HTML, passe "\u{202F}" ou "\u{00A0}" como separador em vez de um espaço comum.
Formatar um número sem separador de milhar
Passe '' como quarto argumento. Você recebe um número simples com um número fixo de casas decimais, o formato que gateways de pagamento, exportações CSV e valores de <input type="number"> esperam:
Na última linha, o round() antes do cast importa: 19.9 * 100 é guardado como 1989.9999999999998, e só o (int) o cortaria para 1989.
Como o number_format arredonda
O number_format() arredonda a metade para longe do zero, como o round(), então 0.5 vira 1 e -2.5 vira -3. Ele também corrige o pequeno erro binário de valores como 2.675, e é por isso que pode discordar do sprintf('%.2f'):
2.675 não pode ser guardado com exatidão em binário; o valor guardado fica um pouquinho abaixo. O sprintf() formata esse valor guardado e dá 2.67, enquanto o number_format() e o round() o tratam como o 2.675 que você escreveu. Se precisar de uma regra de arredondamento específica, chame round(), floor() ou ceil() você mesmo antes (veja arredondamento e matemática) e passe o resultado para o number_format().
Formatar dinheiro e outras moedas
O number_format() não sabe nada de moedas, então você adiciona o símbolo. Coloque o sinal de negativo antes do símbolo, e lembre que o iene não tem casas decimais:
Para uma saída que respeita o locale, com a posição certa do símbolo para cada país, o NumberFormatter da extensão intl faz o trabalho todo:
$fmt = new NumberFormatter('de_DE', NumberFormatter::CURRENCY);
echo $fmt->formatCurrency(1234.5, 'EUR'); // 1.234,50 € (a no-break space before €)
Ele exige a extensão intl, que não está instalada em todo lugar, então o number_format() com o seu próprio símbolo é a escolha portável.
O resultado é uma string, não um número
Esse é o bug mais comum com o number_format(): formatar um valor e depois calcular com ele. "1,234.50" não é uma string numérica, então o PHP lê só o 1 antes da vírgula:
<?php
echo number_format(1234.5, 2) + 1;
Warning: A non-numeric value encountered in /home/index.php on line 2
2
Passar uma string dessas de volta para o number_format() é pior: ele lança TypeError: number_format(): Argument #1 ($num) must be of type int|float, string given. Guarde o número cru para as contas e formate só no momento de imprimir. Se você recebe uma string formatada de um formulário ou de um arquivo, tire os separadores antes:
Para preenchimento, alinhamento ou um sinal de mais na frente do número, use o sprintf(); ele não adiciona separadores de milhar, mas controla largura e sinal.
Perguntas frequentes
Como formato um número com separador de milhar no PHP?
Chame number_format($n): number_format(1234567) retorna "1,234,567". Passe um segundo argumento para as casas decimais: number_format(1234567.891, 2) retorna "1,234,567.89".
Como uso number_format sem vírgula?
Passe uma string vazia como separador de milhar: number_format(1234.5, 2, '.', '') retorna "1234.50". É o formato que APIs de pagamento e arquivos CSV normalmente esperam.
O number_format arredonda ou trunca?
Ele arredonda, com a metade para longe do zero: number_format(2.5) é "3", number_format(-2.5) é "-3" e number_format(2.675, 2) é "2.68". Para cortar as casas decimais, use floor() antes: number_format(floor(2.679 * 100) / 100, 2) dá "2.67".
Como formato números no estilo europeu (1.234,56)?
Troque os separadores com o terceiro e o quarto argumentos: number_format(1234.56, 2, ',', '.') retorna "1.234,56". Os estilos francês e suíço usam um espaço ou um apóstrofo como quarto argumento.
Por que o number_format dá um resultado errado quando somo algo a ele?
O number_format() retorna uma string como "1,234.50", e o PHP lê só o 1 antes da vírgula quando você faz contas com ela. Guarde o número para os cálculos e chame number_format() só na hora de imprimir.