Инструменты для работы с числовыми форматами в PHP

Раздел: Программирование на PHP -> Работа со строками и числами в PHP

Основные методы форматирования чисел

В PHP существует несколько способов привести число к нужному строковому представлению. Выбор зависит от задачи: разделители тысяч, количество десятичных знаков, локаль.

Как отформатировать число с разделителями тысяч и фиксированным числом знаков после запятой?

Наиболее эффективное решение - функция number_format. Она принимает число, количество десятичных знаков, десятичный разделитель и разделитель тысяч.

<?php
$number = 1234567.891;
echo number_format($number, 2, '.', ',');
// Результат: 1,234,567.89
?>
1,234,567.89

Проблема: при передаче очень больших чисел (превышающих размер int/float) number_format может привести к потере точности, так как сначала преобразует в float. Решение: использовать строки и BCMath, либо передавать число как строку, если оно в пределах точности float.

Как задать количество знаков после запятой без разделителей тысяч?

Если нужно только округление до N знаков, можно использовать sprintf с форматом '%.Nf'.

<?php
echo sprintf('%.2f', 123.456);
// 123.46
?>
123.46

Проблема: sprintf использует десятичный разделитель, установленный в локали (setlocale). Если локаль не задана, он может использовать точку, но на некоторых серверах может быть запятая. Для явного задания разделителя лучше использовать number_format.

Как округлить число вниз или вверх до целого или до заданного количества знаков?

Функции floor и ceil округляют дробное число вниз и вверх соответственно. Для округления до определённого количества знаков можно комбинировать с умножением.

<?php
$number = 123.456;
echo floor($number * 100) / 100; // 123.45
echo ceil($number * 100) / 100;  // 123.46
?>
123.45
123.46

Проблема: из-за неточности float операции вида floor/ceil могут дать неверный результат для чисел, которые не точно представимы (например, 0.1). Рекомендуется использовать BCMath для критичных расчётов.

Как отформатировать число в денежном формате с учётом локали?

Класс NumberFormatter из расширения intl предоставляет локализованное форматирование валют, процентов, десятичных чисел.

<?php
$fmt = new NumberFormatter('ru_RU', NumberFormatter::CURRENCY);
echo $fmt->formatCurrency(1234567.89, 'RUB');
?>
1 234 567,89 руб.

Проблема: требуется установленное расширение intl. Без него класс недоступен. Также поведение может различаться в разных версиях ICU.

Каждый из рассмотренных подходов подходит для определённого круга задач. Основным рабочим инструментом остаётся number_format, но для локализации и точных операций стоит обращаться к NumberFormatter и BCMath.

Расширенные примеры и нестандартные сценарии

Ниже приведены примеры, демонстрирующие более сложные или редкие случаи форматирования чисел в PHP.

Пример 1: Форматирование отрицательного числа с сохранением знака

Пример
<?php
$number = -1234567.891;
echo number_format($number, 2, '.', ',');
// Результат: -1,234,567.89
?>
-1,234,567.89

Функция number_format корректно обрабатывает отрицательные числа, помещая знак минус перед числом.

Пример 2: Замена разделителя тысяч через str_replace после number_format

Пример
<?php
$formatted = number_format(1234567.89, 2, '.', ',');
echo str_replace(',', ' ', $formatted);
// Результат: 1 234 567.89
?>
1 234 567.89

Иногда требуется нестандартный разделитель тысяч. Можно преобразовать строку после форматирования.

Пример 3: Использование BCMath для точного округления до 2 знаков

Пример
<?php
$number = '1234567.895';
echo bcadd($number, '0', 2);
// Результат: 1234567.89 (отбрасывание)
echo round($number, 2);
// Может дать 1234567.90 из-за float
?>
1234567.89
1234567.90

При работе с денежными суммами лучше использовать BCMath, так как round на float может дать неожиданный результат из-за двоичного представления.

Пример 4: Форматирование процентов с NumberFormatter

Пример
<?php
$fmt = new NumberFormatter('en_US', NumberFormatter::PERCENT);
echo $fmt->format(0.125);
// Результат: 12%
?>
12%

NumberFormatter автоматически умножает число на 100 и добавляет знак процента. Локализация влияет на положение знака.

Пример 5: Форматирование с фиксированной длиной целой части (ведущие нули)

Пример
<?php
$number = 42;
echo str_pad($number, 5, '0', STR_PAD_LEFT);
// Результат: 00042
?>
00042

Если требуется, чтобы число имело определённое количество цифр, str_pad добавляет нули слева. Можно комбинировать с number_format для десятичной части.

Пример 6: Обработка бесконечности и NaN

Пример
<?php
$inf = INF;
echo number_format($inf, 2);
// Результат: INF (строка)
$nan = NAN;
echo number_format($nan, 2);
// Результат: NAN
?>
INF
NAN

Специальные значения float не форматируются как числа, а просто преобразуются в строку 'INF' или 'NAN'. Перед форматированием стоит проверять через is_finite.

Пример 7: Разделение числа на целую и дробную части с округлением

Пример
<?php
$number = 123.4567;
$intPart = floor($number);
$fracPart = round($number - $intPart, 2);
echo sprintf('%d.%02d', $intPart, abs($fracPart) * 100);
// Результат: 123.46
?>
123.46

Такой ручной подход даёт полный контроль над форматированием, но требует внимания к отрицательным числам и точности.

Эти примеры охватывают типичные и нестандартные задачи форматирования чисел в PHP. Выбор конкретного способа зависит от требуемой точности, локализации и структуры выходных данных.

Форматирование чисел - comments

En
Number format php (php)