Работа с валютой в PHP - десятичные разряды & number_format () - PullRequest
1 голос
/ 07 декабря 2010

Мне нужно хранить числа, которые представляют собой суммы в 2dp для вывода на экран. Это же число может быть изменено математическими функциями после форматирования. Я уверен, что помню, что в прошлом возникали ошибки в результате того, что число в формате числа обрабатывалось как строка, а разделитель тысяч был причиной проблемы, но приведенный ниже скрипт выполняется без ошибок.

Спасают ли свободные типы данных PHP день здесь? Что-то изменилось в относительно недавней версии PHP? Если нет, существуют ли другие обстоятельства, когда number_format() может все еще вызвать сбой математической функции, поскольку число является строкой?

echo round(1111123.2, 2); //included to demonstrate how it can't be used for this purpose
echo "<br />";
echo number_format(1111123.2, 2);
echo "<br />";
$num = number_format(1111123.2, 2);
echo number_format($num / 42, 2);

// output
1111123.2
1,111,123.20
0.02

Ответы [ 4 ]

2 голосов
/ 07 декабря 2010

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

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

1 голос
/ 07 декабря 2010

Это происходит из-за автоматического приведения типов в PHP.Насколько я понимаю, PHP будет способен приводить числа к типам в большинстве общих математических функций, хотя все еще не совсем уверен в этом.Строки преобразуются в требуемые типы переменных

0 голосов
/ 30 марта 2013

Лучше использовать класс форматирования чисел:

, однако для него требуется расширение intl и php 5.3.0+ .. (sudo apt-get install php5-intl)

$f = NumberFormatter::create("en-US",NumberFormatter::CURRENCY);
var_dump($f->format(1111123.2));
$f = NumberFormatter::create("en-US",NumberFormatter::CURRENCY);
$f->setSymbol(NumberFormatter::CURRENCY_SYMBOL,"€");
var_dump($f->format(1111123.2));
$f = NumberFormatter::create("de_DE",NumberFormatter::CURRENCY);
var_dump($f->formatCurrency(1111123.2,"EUR"));
$f = NumberFormatter::create("it_IT",NumberFormatter::CURRENCY);
var_dump($f->formatCurrency(1111123.2,"USD"));
$f = NumberFormatter::create("sk_SK",NumberFormatter::CURRENCY);
var_dump($f->formatCurrency(1111123.2,"USD"));

Возвраты:

string(13) "$1,111,123.20"
string(15) "€1,111,123.20"
string(17) "1.111.123,20 €"
string(17) "US$ 1.111.123,20"
string(19) "1 111 123,20 US$"

Если ваши клиенты из разных стран, просто сохраните для них локаль, и они получат заранее определенный номер.

0 голосов
/ 07 декабря 2010

Ну ... Лучше всего хранить и вычислять с "реальными" числами (float, double или int) и использовать number_format() только для представления.
Но если вам нужновычислите с цифрами, которые были возвращены из number_format(), подумайте о написании такой функции, как

function unNumber_Format($str) {
   $search  = array(',', '$', '€');
   $replace = array('', '', '');

   return (double) str_replace($search, $replace, $str);
}

и использовании ее как

echo number_format(unNumber_Format($num) / 42, 2);

, и все в порядке!; -)

...