12

I'm trying to use money_format function.

<?php

$number = 1299.46;

setlocale(LC_MONETARY, 'en_US');
echo money_format('%i', $number); // Outputs 1299.46

While it should print $ sign or USD ?

I'm on linux hosting.

Thanks

Syscall
  • 19,327
  • 10
  • 37
  • 52
Raheel
  • 8,716
  • 9
  • 60
  • 102
  • I can't replicate the issue you are having. Tested 5.6.2 - 4.4.9 all have USD. http://sandbox.onlinephpfunctions.com/code/5e8c4ba1962be5ed422a177e35e6762281b8eda3 – chris85 Jun 20 '15 at 17:47
  • when i used 'en_US.UTF-8' it prints USD – Raheel Jun 20 '15 at 17:48

4 Answers4

15

money_format will not work properly if locale is not valid.

For example, on Debian, 'en_US' is not a valid locale - you need 'en_US.UTF-8' or 'en_US.ISO-8559-1'.

Samir Das
  • 1,878
  • 12
  • 20
  • Damn it worked ! I don't understand why people above are marking my question negative. – Raheel Jun 20 '15 at 17:45
  • Seems they did not understand the question :) Anyway good to hear it is working – Samir Das Jun 20 '15 at 17:47
  • I ran into this issue with a shared server at Network Solutions and the problem is they don't support locale at all on their shared servers. Luckily in my case I was just dealing with US currency so I used `number_format()` instead and just prepended the '$'. Like this: `$result = '$' . number_format(120000);` which returns: $120,000. – Adam Christianson Mar 14 '16 at 21:27
5

Locales are constants defined by the operation system.

I use Ubuntu for the following example.

  1. check which locales are supported:

    locale -a
    
  2. add the locales you want (for example ru):

    sudo locale-gen ru_RU
    sudo locale-gen ru_RU.UTF-8
    
  3. run this update comand

    sudo update-locale 
    
  4. restart php fpm ( check your php version service name like soservice --status-all)

    sudo service php7.2-fpm restart
    

But be careful, because most likely you are useing Apache with "mod_php" because it is the most popular one. And this one works in multi thread environment, when setlocale() is not thread safe. Look here for details

Yevgeniy Afanasyev
  • 37,872
  • 26
  • 173
  • 191
1

First you must know php version is using

If you are unsure how to check create a file called info.php

Insert code => <?php phpinfo(); ?>

(PHP 4 >= 4.3.0, PHP 5)
$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

Note: The function money_format() is only defined if the system has strfmon capabilities. For example, Windows does not, so money_format() is undefined in Windows.

You can use an alternative (PHP 5 >= 5.3.0, PECL intl >= 1.0.0)

Example #1 numfmt_format_currency() example

$fmt = numfmt_create( 'de_DE', NumberFormatter::CURRENCY );
echo numfmt_format_currency($fmt, 1234567.891234567890000, "EUR")."\n";
echo numfmt_format_currency($fmt, 1234567.891234567890000, "RUR")."\n";
$fmt = numfmt_create( 'ru_RU', NumberFormatter::CURRENCY );
echo numfmt_format_currency($fmt, 1234567.891234567890000, "EUR")."\n";
echo numfmt_format_currency($fmt, 1234567.891234567890000, "RUR")."\n";

Example #2 OO example

$fmt = new NumberFormatter( 'de_DE', NumberFormatter::CURRENCY );
echo $fmt->formatCurrency(1234567.891234567890000, "EUR")."\n";
echo $fmt->formatCurrency(1234567.891234567890000, "RUR")."\n";
$fmt = new NumberFormatter( 'ru_RU', NumberFormatter::CURRENCY );
echo $fmt->formatCurrency(1234567.891234567890000, "EUR")."\n";
echo $fmt->formatCurrency(1234567.891234567890000, "RUR")."\n";

The above example will output:

1.234.567,89 €
1.234.567,89 RUR
1 234 567,89€
1 234 567,89р.

Examples taken from php.net

If the alternative is not possible, the solution is to create a method for your needs.

I hope helped you

0

It shouldn't give $ or USD back, consult the documentation. However you can do the following:

echo money_format('$%i', $number)

This will give the expected result but ofcourse it is not a dynamic solution.

Anth Bieb
  • 395
  • 1
  • 4
  • 11
  • Yes actually i want to obtain some dynamic solution. For example a user comes from UK so he should se EUR instead of USD. I thought `setlocate` would handle this thing. – Raheel Jun 20 '15 at 17:35
  • You should add the dynamic requirement to the question. – chris85 Jun 20 '15 at 17:45
  • from php.net i was trying: money_format('%(#10n', $Admin_amt); their site implied directly that a $ sign would appear. it did not. your example helped me think to put the $ before the %, and it works. thank you! php.net literally shows[i rearranged a little, to fit here; but see how it shows $ will appear: // Using a negative number, $number = -1234.5672; // US national format, using () for neg numbers and 10 digits for left precision setlocale(LC_MONETARY, 'en_US'); echo money_format('%(#10n', $number) . "\n"; // ($ 1,234.57) – dcparham Aug 24 '18 at 21:35