Money format: примеры (PHP)

Функция форматирования денежных значений money_format в PHP
Раздел: Форматирование
money_format(string $format, float $number): string

Основы функции money_format

Назначение и применение

Функция money_format предназначена для форматирования чисел как денежных значений с учетом региональных настроек. Она преобразует число в строку, представляющую валюту, согласно установленной локали. Эта функция особенно полезна при разработке интернациональных приложений, где требуется отображение денежных единиц в формате, привычном для пользователя из конкретной страны.

Синтаксис и аргументы

Синтаксис функции: money_format(string $format, float $number).

Функция принимает два аргумента:

  1. $format - строка формата, определяющая как будет отображаться результат. Содержит спецификаторы преобразования, начинающиеся с символа процента (%).
  2. $number - числовое значение (float), которое требуется отформатировать как денежную сумму.
Спецификаторы формата

Строка формата строится из следующих компонентов:

  • % - обязательный начальный символ спецификатора.
  • Флаги (опционально):
    • =f - символ заполнения f (один символ).
    • ^ - отключение группировки символов (например, тысяч).
    • + или ( - определение способа отображения положительных и отрицательных чисел.
    • ! - удаление символа валюты из выходной строки.
    • - - выравнивание влево. Если не указано, выравнивание по умолчанию - вправо.
  • Поле ширины (опционально): десятичное число, определяющее минимальную ширину поля.
  • # (опционально): десятичное число, определяющее точность (количество цифр после десятичного разделителя).
  • i - собственно спецификатор преобразования, определяющий применение локали.

Базовые примеры использования

Простое форматирование

Форматирование числа согласно текущей локали.

<?php
setlocale(LC_MONETARY, 'en_US');
$number = 1234.56;
echo money_format('%i', $number);
?>
USD 1,234.56
Форматирование с указанием ширины поля
<?php
setlocale(LC_MONETARY, 'en_US');
$number = 1234.56;
echo money_format('%#10n', $number);
?>
  $1,234.56
Использование флага заполнения
<?php
setlocale(LC_MONETARY, 'de_DE');
$number = 1234.56;
echo money_format('%=*#10n', $number);
?>
*1.234,56 €
Отключение группировки
<?php
setlocale(LC_MONETARY, 'en_US');
$number = 1234567.89;
echo money_format('%^#10i', $number);
?>
USD 1234567.89
Отрицательные числа
<?php
setlocale(LC_MONETARY, 'en_US');
$number = -1234.56;
echo money_format('%+#10n', $number);
?>
-$1,234.56

Альтернативные функции в PHP

Функция number_format форматирует число с группировкой тысяч. Она не зависит от локали и не использует символы валют. Подходит для отображения чисел, где важна только группировка разрядов.

<?php
echo number_format(1234.56, 2, ',', ' ');
?>
1 234,56
NumberFormatter (класс из intl)

Класс NumberFormatter из расширения Intl предоставляет наиболее мощные и гибкие возможности форматирования чисел, валют и процентов с полной поддержкой локализации. Рекомендуется к использованию в современных приложениях вместо устаревшей money_format.

<?php
$formatter = new NumberFormatter('ru_RU', NumberFormatter::CURRENCY);
echo $formatter->formatCurrency(1234.56, 'RUB');
?>
1 234,56 ₽
sprintf

Функция sprintf позволяет форматировать строки с использованием различных спецификаторов. Для денежных значений может комбинироваться с number_format.

<?php
$formatted = number_format(1234.5, 2);
echo sprintf('$%s', $formatted);
?>
$1,234.50

Типичные ошибки и проблемы

Не установлена локаль

Функция зависит от установленной локали. Если локаль не установлена или не поддерживается, функция может вернуть false или некорректный результат.

<?php
// Локаль не установлена
$result = money_format('%i', 1234.56);
var_dump($result);
?>
bool(false)
Некорректный спецификатор формата

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

<?php
setlocale(LC_MONETARY, 'en_US');
echo money_format('%d', 1234.56); // %d - неверный спецификатор
?>
Warning: money_format(): Illegal format identifier...
Проблемы с локалями в Windows

В Windows имена локалей отличаются от Unix-подобных систем.

<?php
// Для Windows
setlocale(LC_MONETARY, 'English_United States.1252');
?>
Ошибки с отрицательными числами

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

<?php
setlocale(LC_MONETARY, 'en_US');
$number = -1234.56;
echo money_format('%i', $number);
?>
-USD 1,234.56

Изменения в версиях PHP

Устаревание и удаление

Функция money_format была объявлена устаревшей в PHP 7.4. В PHP 8.0 функция была удалена из ядра языка. Это связано с тем, что функция сильно зависела от системных локалей C library и имела ограниченную переносимость между операционными системами.

Рекомендуемая замена

Вместо удаленной money format рекомендуется использовать класс NumberFormatter из расширения Intl, который предоставляет более надежное и кросс-платформенное решение для форматирования валют.

<?php
// Современная альтернатива для PHP 8+
$formatter = new NumberFormatter('en_US', NumberFormatter::CURRENCY);
echo $formatter->format(1234.56);
?>
$1,234.56

Расширенные примеры использования

Форматирование для разных стран

Сравнение форматирования одной суммы для различных локалей.

Пример php
<?php
$amount = 1234567.89;
$locales = ['en_US', 'de_DE', 'fr_FR', 'ja_JP'];

foreach ($locales as $locale) {
    setlocale(LC_MONETARY, $locale);
    echo $locale . ': ' . money_format('%i', $amount) . "\n";
}
?>
en_US: USD 1,234,567.89
de_DE: 1.234.567,89 €
fr_FR: 1 234 567,89 €
ja_JP: JPY 1,234,567.89
Кастомное форматирование с разными флагами
Пример php
<?php
setlocale(LC_MONETARY, 'en_US');
$number = 1234.567;

// Разные комбинации флагов
echo "Базовое: " . money_format('%i', $number) . "\n";
echo "Без символа: " . money_format('%.2n', $number) . "\n";
echo "Заполнение: " . money_format('%=*#15i', $number) . "\n";
echo "Выравнивание влево: " . money_format('%=*-15i', $number) . "\n";
?>
Базовое: USD 1,234.57
Без символа: 1,234.57
Заполнение: ***USD 1,234.57
Выравнивание влево: USD 1,234.57***
Форматирование финансовых отчетов

Создание выровненных колонок с денежными значениями.

Пример php
<?php
setlocale(LC_MONETARY, 'en_US');
$payments = [
    ['description' => 'Product A', 'amount' => 1500.75],
    ['description' => 'Product B', 'amount' => 89.50],
    ['description' => 'Service fee', 'amount' => -25.00],
    ['description' => 'Total', 'amount' => 1565.25]
];

foreach ($payments as $item) {
    printf("%-20s %=15i\n", 
           $item['description'], 
           $item['amount']);
}
?>
Product A              USD 1,500.75
Product B              USD 89.50
Service fee           -USD 25.00
Total                 USD 1,565.25
Обработка разных валют в одной локали

money_format использует валюту по умолчанию для локали, но можно имитировать разные валюты.

Пример php
<?php
setlocale(LC_MONETARY, 'en_US');
$amount = 1000;

// Имитация разных валют через манипуляцию выводом
$formats = [
    'USD' => '%i',
    'EUR' => '€%.2n',
    'GBP' => '£%.2n'
];

foreach ($formats as $currency => $format) {
    echo $currency . ': ' . money_format($format, $amount) . "\n";
}
?>
USD: USD 1,000.00
EUR: €1,000.00
GBP: £1,000.00

Аналоги в других языках программирования

Python: locale.currency

Модуль locale в Python предоставляет функцию currency для форматирования денежных значений.

import locale
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
print(locale.currency(1234.56, grouping=True))
$1,234.56
JavaScript: Intl.NumberFormat

В JavaScript для форматирования валют используется конструктор Intl.NumberFormat.

const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
});
console.log(formatter.format(1234.56));
$1,234.56
MySQL: FORMAT

Функция FORMAT в MySQL форматирует число с указанным количеством десятичных знаков и группировкой тысяч.

SELECT FORMAT(1234.56, 2);
1,234.56
Отличия от PHP

Основное отличие money_format в PHP от аналогов в других языках - сильная зависимость от установленной локали системы. В Python и JavaScript подход более объектно-ориентированный и часто предоставляет больше настроек через параметры функций или объектов. Решение в JavaScript (Intl) является частью стандарта ECMAScript и работает единообразно в разных средах.

PHP money_format function comments

En
Money format Formats a number as a currency string