number_format($number, $decimals) devuelve el número como cadena con un separador de miles y un número fijo de decimales: number_format(1234567.891, 2) devuelve "1,234,567.89". Con un solo argumento redondea a un número entero: number_format(1234567.891) es "1,234,568".
Los cuatro parámetros
number_format(
float $num,
int $decimals = 0,
?string $decimal_separator = ".",
?string $thousands_separator = ","
): string
El tercer argumento es el carácter entre la parte entera y los decimales, y el cuarto el carácter entre los grupos de tres dígitos. Cualquiera de los dos puede ser cualquier cadena, incluida una vacía o un carácter multibyte. Edita los separadores de abajo para ver cada estilo:
Los datos regionales (CLDR) usan un espacio estrecho de no separación (U+202F) para el francés y un espacio de no separación (U+00A0) para el ruso, para que un número nunca se parta en dos líneas. En HTML, pasa "\u{202F}" o "\u{00A0}" como separador en lugar de un espacio normal.
Formatear un número sin separador de miles
Pasa '' como cuarto argumento. Obtienes un número simple con un número fijo de decimales, la forma que esperan las pasarelas de pago, las exportaciones CSV y los valores de <input type="number">:
En la última línea, el round() antes del cast importa: 19.9 * 100 se guarda como 1989.9999999999998, y (int) solo lo cortaría en 1989.
Cómo redondea number_format
number_format() redondea la mitad alejándose de cero, como round(), así que 0.5 se convierte en 1 y -2.5 en -3. También corrige el pequeño error binario de valores como 2.675, y por eso puede no coincidir con sprintf('%.2f'):
2.675 no se puede guardar exactamente en binario; el valor guardado está un pelo por debajo. sprintf() formatea ese valor guardado y obtiene 2.67, mientras que number_format() y round() lo tratan como el 2.675 que escribiste. Si necesitas una regla de redondeo concreta, llama tú antes a round(), floor() o ceil() (consulta redondeo y matemáticas) y pasa el resultado a number_format().
Formatear dinero y otras monedas
number_format() no sabe nada de monedas, así que añades tú el símbolo. Pon el signo negativo antes del símbolo, y recuerda que el yen no tiene decimales:
Para una salida según la configuración regional, con el símbolo en la posición correcta para cada país, el NumberFormatter de la extensión intl hace todo el trabajo:
$fmt = new NumberFormatter('de_DE', NumberFormatter::CURRENCY);
echo $fmt->formatCurrency(1234.5, 'EUR'); // 1.234,50 € (a no-break space before €)
Requiere la extensión intl, que no está instalada en todas partes, así que number_format() con tu propio símbolo es la opción portable.
El resultado es una cadena, no un número
Este es el bug más común con number_format(): formatear un valor y luego calcular con él. "1,234.50" no es una cadena numérica, así que PHP solo lee el 1 antes de la coma:
<?php
echo number_format(1234.5, 2) + 1;
Warning: A non-numeric value encountered in /home/index.php on line 2
2
Volver a pasar una cadena así a number_format() es peor: lanza TypeError: number_format(): Argument #1 ($num) must be of type int|float, string given. Guarda el número sin formato para los cálculos y formatea solo en el momento de imprimir. Si recibes una cadena formateada de un formulario o de un archivo, quita antes los separadores:
Para relleno, alineación o un signo más delante del número, usa sprintf(); no añade separadores de miles, pero controla el ancho y el signo.
Preguntas frecuentes
¿Cómo formateo un número con comas en PHP?
Llama a number_format($n): number_format(1234567) devuelve "1,234,567". Pasa un segundo argumento para los decimales: number_format(1234567.891, 2) devuelve "1,234,567.89".
¿Cómo uso number_format sin coma?
Pasa una cadena vacía como separador de miles: number_format(1234.5, 2, '.', '') devuelve "1234.50". Es la forma que suelen esperar las APIs de pago y los archivos CSV.
¿number_format redondea o trunca?
Redondea, la mitad alejándose de cero: number_format(2.5) es "3", number_format(-2.5) es "-3" y number_format(2.675, 2) es "2.68". Para cortar los decimales, usa antes floor(): number_format(floor(2.679 * 100) / 100, 2) da "2.67".
¿Cómo formateo números al estilo europeo (1.234,56)?
Intercambia los separadores con el tercer y el cuarto argumento: number_format(1234.56, 2, ',', '.') devuelve "1.234,56". Los estilos francés y suizo usan un espacio o un apóstrofo como cuarto argumento.
¿Por qué number_format da un resultado incorrecto cuando le sumo algo?
number_format() devuelve una cadena como "1,234.50", y PHP solo lee el 1 antes de la coma cuando haces cálculos con ella. Guarda el número para los cálculos y llama a number_format() solo cuando lo imprimas.