PHP money_format not displaying currency symbol - php

I'm trying to use money_format() to obviously add separators and a currency symbol to a number I have. I've seen plenty of examples where they work, but for some reason the currency symbol does not display.
$_price = '10995';
setlocale(LC_MONETARY, 'en_GB.UTF-8');
echo money_format('%n', $_price);
results in:
10995.00
I can do this and it nearly works, however as I understand, that's not the point?:
echo money_format('£%n', $_price);
results in:
£10995.00
I can see that this also formats the number close to how I want, without the .00:
echo '£'.number_format( $_price );
results in:
£10,995

From Sean's link in the above comment, I can see that the locale for en_GB was not created.
once created with sudo locale-gen en_GB.UTF-8 I had the currency symbol

Related

How to set currency to setlocale / money_format in PHP

setlocale is taking a country and a language as parameters.
'money_format' is taking amount and other params.
But how can I tell a currency to PHP?
What if I want to use EUR in Australia?
like javascript can:
var formatter = new Intl.NumberFormat('en-AU', {
style: 'currency',
currency: 'EUR',
});
formatter.format(2500);
Chrome obviously understands that it is a foreign currency that need to be formatted to international currency format like so "EUR 2,500.00".
IE does not understand it, but it offers something "€2,500.00"
PHP (that is how I use it)
setlocale(LC_MONETARY, 'en-AU');
return money_format('%.2n', 2500);
gives "$2,500.00" (I know it is Ubuntu should be blamed)
It takes some default currency for Australia and I cannot find a way to change it. Is there a formatting library or something that I'm missing that can help?
Java script does not require installing locales individually, like Ubuntu does.
Maybe should we rely on Browsers in this case?
You can use the NumberFormatter in the intl extension instead.
$fmt = new NumberFormatter('en_AU.UTF8', NumberFormatter::CURRENCY);
print $fmt->formatCurrency(2500, 'EUR');
And it doesn't require to install every locale individually, since it ships with its own locale data.

NumberFormatter::formatCurrency is not showing a currency symbol

I'm using NumberFormatter::formatCurrency to display formatted currency values, like this;
$value = 395;
$fmt = numfmt_create('en_GB', NumberFormatter::CURRENCY);
echo numfmt_format_currency($fmt, $value, 'gbp');
On my Windows dev box, and Centos UAT box, this outputs the desired £395.
But on the production Centos box, it outputs gbp395.
Any idea what is missing? I have checked intl extension is enabled.
Is there something wrong with my locale files perhaps? When I type
locale -a
in command line, I get a long list of locales, of which en_GB is one.
Maybe en_GB is not a valid locale on your system. Try en_GB.UTF-8 or en_GB.ISO-8559-1 f.e.
The NumberFormatter class is incorrect and the GBP needs to be in capital like so:'GBP'
Try this:
$value = 395;
$currencyFormat = new NumberFormatter('en_GB', NumberFormatter::CURRENCY);
echo $currencyFormat->formatCurrency($value, 'GBP');
This will render £395.00

LC_MONETARY it_IT#utf8 shows euro symbol before amount with PHP

Setting the locale information as:
$locale = 'it_IT';
$moneyFormat = '%n';
setlocale(LC_MONETARY, $locale.'.utf8');
$optionPrice = money_format($moneyFormat, floatval($option->optionPrice));
The price is shown as:
€ 23
instead
23 €
I've found the locale identifier p_sign_posn to set the position of the currency symbol but I don't know how to modify it and apparently it's set by default to 1 for the IT locale.
Anybody could enlightenment me to find a clever solution?
Thanks in advance.
EDIT: The locale for Italy is apparently installed on the system
vmamp#AMP30:~> locale -a | grep it
it_CH
it_CH.utf8
it_IT
it_IT.utf8
it_IT#euro
To use locale-aware function you have to have the requested locale installed on your computer. If the requested locale is not presented, the call to setlocale fails and nothing is changed.
For instance, I have es_ES locale installed, but no it_IT:
setlocale(LC_MONETARY, 'es_ES.utf8');
echo money_format($moneyFormat, floatval(12))
// ⇒ 12,00 €
setlocale(LC_MONETARY, 'en_US.utf8');
echo money_format($moneyFormat, floatval(12))
// ⇒ $12.00
setlocale(LC_MONETARY, 'it_IT.utf8');
echo money_format($moneyFormat, floatval(12))
// FAIL!!!
// ⇒ $12.00
As you can see, the latter call was ignored (setlocale returned 0.) So the problem you encountered is not with a position of eurosign; it’s likely a lack of it_IT l10n installed.
For italian currency mode you can do:
$money = substr(money_format('%.2n',$number), 4).' €';
given $number = 77500
you get
77.500,00 €

Writing the good format of a currency in PHP

When we write an invoice, we have to respect the money format
For example :
in France, you will write 1000,00 €
In the USA, $ 1,000.00
I would like to know if it is handled by some PHP library ? especially the money symbol at the left or right.
Edit :
I have never been downvoted like this and i think my question wasn't that well asked. Sorry for that.
I already know different formatting functions in PHP and I understand that the formatter options should be selected for each country and their money format. Thou, i don't have the time to do that job.
My objective is to format any money values for all possible locales in the world without registering all those locales.
Maybe somebody wrote a class which can do the job but I didn't find it.
Btw I know it is difficult, I can for example talk of the example of the EUR.
In many contry they write EUR xxxxx. In some countries, it is written xxxx EUR.
Yep, by the intl module.
For currencies there is a NumberFormater class:
http://www.php.net/manual/en/numberformatter.formatcurrency.php
http://ru2.php.net/number_format will help you.
You can simply setup it by yourself using number_format(). Save rule for each currency in db then apply on view regarding it's type.
The basic PHP function money_format can handle your output quite well.
If you need more, check out the Money PHP Library. IT is very powerfull.
From the Documentation:
<?php
$number = 1234.56;
// let's print the international format for the en_US locale
setlocale(LC_MONETARY, 'en_US');
echo money_format('%i', $number) . "\n";
// USD 1,234.56
// Italian national format with 2 decimals`
setlocale(LC_MONETARY, 'it_IT');
echo money_format('%.2n', $number) . "\n";
// Eu 1.234,56
// Using a negative number
$number = -1234.5672;
// US national format, using () for negative numbers
// and 10 digits for left precision
setlocale(LC_MONETARY, 'en_US');
echo money_format('%(#10n', $number) . "\n";
// ($ 1,234.57)
// Similar format as above, adding the use of 2 digits of right
// precision and '*' as a fill character
echo money_format('%=*(#10.2n', $number) . "\n";
// ($********1,234.57)

NumberFormatter::formatCurrency() ignores MIN_FRACTION_DIGITS

I want to use PHP's Intl's NumberFormatter class to display prices in a human-readable format. What our project needs:
The CLDR number pattern, and the currency and separator symbols will need to be configured through our code and not default to what Intl/ICU knows.
Our application will take care of the decimals. NumberFormatter should display any decimals that we pass on to it.
However, when playing around with different configurations to find the exact combination that works for our project, I noticed some effects that I can't explain. The three formatters in the following code snippet are almost identical. As opposed to the first one, the second one uses the euro instead of the U.S. dollar, and the third one has a currency sign set. The output of the first formatter is as I expected it to be, but when I change the currency or set a currency sign, the MIN_FRACTION_DIGITS attribute is ignored and the sign is never changed.
<?php
$fmt = new NumberFormatter('de_DE', NumberFormatter::CURRENCY);
$fmt->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, 4);
echo $fmt->formatCurrency(1234567890.891234567890000, "EUR")."\n";
// Outputs 1.234.567.890,8912 €
$fmt = new NumberFormatter('de_DE', NumberFormatter::CURRENCY);
$fmt->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, 4);
echo $fmt->formatCurrency(1234567890.891234567890000, "USD")."\n";
// Ouputs 1.234.567.890,89 $
$fmt = new NumberFormatter('de_DE', NumberFormatter::CURRENCY);
$fmt->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, 4);
$fmt->setSymbol(\NumberFormatter::CURRENCY_SYMBOL, '%');
echo $fmt->formatCurrency(1234567890.891234567890000, "EUR")."\n";
// Outputs 1.234.567.890,89 €
?>
The first table row under General Purpose Numbers of the Unicode CLDR number pattern documentation describes that when parsing currency patterns, the two zeroes in the decimal part of the pattern will need to be replaced by however many digits the application thinks is appropriate. The application here is ICU (the C library that PHP uses for this), and the MIN_FRACTION_DIGITS attribute does its job of letting me override default behavior in the first example, but not in the second or the third.
Can someone please explain this seemingly random change in behavior? Let me know if there is any additional information that you need.
I just found the following:
https://bugs.php.net/bug.php?id=63140
http://bugs.icu-project.org/trac/ticket/7667
[2012-10-05 08:21 UTC] jpauli#email.com
I confirm this is an ICU bug in 4.4.x branch.
Consider upgrading libicu, 4.8.x gives correct result

Categories