Menu

PHP number_format(): разделитель тысяч и знаки после запятой

number_format(1234567.891, 2) возвращает "1,234,567.89": функция округляет до заданного числа знаков и добавляет разделитель тысяч. Четыре параметра, европейский и японский форматы, как она округляет и почему результат это строка.

На этой странице есть исполняемые редакторы: меняйте, запускайте и сразу видите результат.

number_format($number, $decimals) возвращает число строкой с разделителем тысяч и фиксированным числом знаков после запятой: number_format(1234567.891, 2) возвращает "1,234,567.89". С одним аргументом функция округляет до целого: number_format(1234567.891) даёт "1,234,568".

Четыре параметра

number_format(
    float $num,
    int $decimals = 0,
    ?string $decimal_separator = ".",
    ?string $thousands_separator = ","
): string

Третий аргумент это символ между целой частью и дробной, четвёртый символ между группами из трёх цифр. Любым из них может быть любая строка, в том числе пустая или многобайтовый символ. Измените разделители ниже, чтобы увидеть каждый стиль:

Данные локалей (CLDR) используют узкий неразрывный пробел (U+202F) для французского и неразрывный пробел (U+00A0) для русского, чтобы число никогда не переносилось на две строки. В HTML передавайте разделителем "\u{202F}" или "\u{00A0}" вместо обычного пробела.

Число без разделителя тысяч

Передайте '' четвёртым аргументом. Получится простое число с фиксированным числом знаков после запятой, именно такое ждут платёжные шлюзы, экспорт в CSV и значения <input type="number">:

В последней строке важен round() перед приведением: 19.9 * 100 хранится как 1989.9999999999998, и один (int) обрезал бы его до 1989.

Как округляет number_format

number_format() округляет половину от нуля, как round(), поэтому 0.5 становится 1, а -2.5 становится -3. Ещё она исправляет крошечную двоичную ошибку в значениях вроде 2.675, поэтому может расходиться со sprintf('%.2f'):

2.675 нельзя точно сохранить в двоичном виде; сохранённое значение чуть меньше. sprintf() форматирует это сохранённое значение и получает 2.67, а number_format() и round() считают его тем 2.675, которое вы написали. Если нужно определённое правило округления, сами вызовите round(), floor() или ceil() (смотрите округление и математику) и передайте результат в number_format().

Деньги и другие валюты

number_format() ничего не знает о валютах, поэтому символ добавляйте сами. Ставьте знак минус перед символом и помните, что у иены нет дробной части:

Для вывода с учётом локали и правильным положением символа в каждой стране всю работу делает NumberFormatter из расширения intl:

$fmt = new NumberFormatter('de_DE', NumberFormatter::CURRENCY);
echo $fmt->formatCurrency(1234.5, 'EUR'); // 1.234,50 € (a no-break space before €)

Ему нужно расширение intl, которое установлено не везде, поэтому number_format() со своим символом это переносимый выбор.

Результат это строка, а не число

Самая частая ошибка с number_format(): отформатировать значение, а потом с ним считать. "1,234.50" не числовая строка, поэтому PHP читает только 1 до запятой:

<?php
echo number_format(1234.5, 2) + 1;
Warning: A non-numeric value encountered in /home/index.php on line 2
2

Передать такую строку обратно в number_format() ещё хуже: она выбрасывает TypeError: number_format(): Argument #1 ($num) must be of type int|float, string given. Храните исходное число для математики и форматируйте только в момент вывода. Если отформатированная строка пришла из формы или файла, сначала уберите разделители:

Для дополнения, выравнивания или знака плюс перед числом используйте sprintf(): она не добавляет разделители тысяч, но управляет шириной и знаком.

Часто задаваемые вопросы

Как отформатировать число с разделителями разрядов в PHP?

Вызовите number_format($n): number_format(1234567) возвращает "1,234,567". Передайте второй аргумент для знаков после запятой: number_format(1234567.891, 2) возвращает "1,234,567.89".

Как использовать number_format без запятой?

Передайте пустую строку как разделитель тысяч: number_format(1234.5, 2, '.', '') возвращает "1234.50". Именно такую форму обычно ждут платёжные API и CSV-файлы.

number_format округляет или отбрасывает?

Округляет, половину от нуля: number_format(2.5) даёт "3", number_format(-2.5) даёт "-3", а number_format(2.675, 2) даёт "2.68". Чтобы вместо этого отбросить знаки, сначала используйте floor(): number_format(floor(2.679 * 100) / 100, 2) даёт "2.67".

Как форматировать числа по-европейски (1.234,56)?

Поменяйте разделители третьим и четвёртым аргументами: number_format(1234.56, 2, ',', '.') возвращает "1.234,56". Во французском, русском и швейцарском стилях четвёртым аргументом служит пробел или апостроф.

Почему number_format даёт неверный результат, если к нему что-то прибавить?

number_format() возвращает строку вроде "1,234.50", и в арифметике PHP читает из неё только 1 до запятой. Храните число для вычислений и вызывайте number_format() только при выводе.

Иллюстрация языков программирования Coddy

Учитесь программировать с Coddy

НАЧАТЬ