Alternative to Money_Format() Function

Alternative to money_format() function

If you have the Intl extension, you can use

  • NumberFormatter::formatCurrency — Format a currency value according to the formatter rules.

Example from Manual

$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";

Output

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

Also see my answer on how to parse that formatted money string back into a float:

  • PHP: unformat money

Defining cross-platform money_format function (Linux and Windows)

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.

So you can use this php code:

setlocale(LC_ALL, ''); // Locale will be different on each system.
$amount = 1000000.97;
$locale = localeconv();
echo $locale['currency_symbol'], number_format($amount, 2, $locale['decimal_point'], $locale['thousands_sep']);

With this you can write code that is actually portable instead of relying on operating system features. Having the money_format function available in PHP without it being an extension is pretty stupid. I don’t see why you would want to create inconsistencies like this between different operating systems in a programming language

php money_format

Try using this version of the money_format() function:

money_format('%.0n', $mon);

According to the PHP documentation on money_format (http://us.php.net/manual/en/function.money-format.php), making the format string '%.2n' will force the number to be displayed with the decimal point and 2 decimal places to the right of the decimal point, no matter what the cents are, and then format the number according the the locale's national currency format.

By replacing that with '%.0n', you will always remove the decimal at the end of the money. Of course, this will remove the decimal for all values, not just those with .00 at the end. If you want to conditionally remove the .00, check to see if the value of $mon has a fractional part, and if so, display it with '%0.2n'.

alternative built-in function to use ? or any code snippets you got there?

Closest you can get is number_format

If you need it just to be able to develop on windows you can simply do:

<?php
if(!function_exists('money_format') {
include('Dani\'s answer.php');
}
echo money_format('%n', $_SESSION["shoppingbag"]->getSubTotal()); ?>

How do I format a number to a dollar amount in PHP

PHP also has money_format().

Here's an example:

echo money_format('$%i', 3.4); // echos '$3.40'

This function actually has tons of options, go to the documentation I linked to to see them.

Note: money_format is undefined in Windows.


UPDATE: Via the PHP manual: https://www.php.net/manual/en/function.money-format.php

WARNING: This function [money_format] has been DEPRECATED as of PHP 7.4.0. Relying on this function is highly discouraged.

Instead, look into NumberFormatter::formatCurrency.

    $number = "123.45";
$formatter = new NumberFormatter('en_US', NumberFormatter::CURRENCY);
return $formatter->formatCurrency($number, 'USD');

Arbitrary precision number formatting / money_format?

Cobbled together from the commenter-submitted functions on PHP's site here and here. Edited to work with arbitrary-precision parameters.

class format {
function money($format, $number)
{
// Takes plain-format, arbitrary-length decimal string (eg: '123456789123456789.123456')
// Returns localized monetary string, truncated at the hundredth value after the decimal point.
// (eg: $ 123,456,789,123,456,789.12)
$regex = '/%((?:[\^!\-]|\+|\(|\=.)*)([0-9]+)?'.
'(?:#([0-9]+))?(?:\.([0-9]+))?([in%])/';
if (setlocale(LC_MONETARY, 0) == 'C') {
setlocale(LC_MONETARY, '');
}
$locale = localeconv();
preg_match_all($regex, $format, $matches, PREG_SET_ORDER);
foreach ($matches as $fmatch) {
$value = (string) $number;
$flags = array(
'fillchar' => preg_match('/\=(.)/', $fmatch[1], $match) ?
$match[1] : ' ',
'nogroup' => preg_match('/\^/', $fmatch[1]) > 0,
'usesignal' => preg_match('/\+|\(/', $fmatch[1], $match) ?
$match[0] : '+',
'nosimbol' => preg_match('/\!/', $fmatch[1]) > 0,
'isleft' => preg_match('/\-/', $fmatch[1]) > 0
);
$width = trim($fmatch[2]) ? (int)$fmatch[2] : 0;
$left = trim($fmatch[3]) ? (int)$fmatch[3] : 0;
$right = trim($fmatch[4]) ? (int)$fmatch[4] : $locale['int_frac_digits'];
$conversion = $fmatch[5];

$positive = true;
if ($value[0] == '-') {
$positive = false;
$value = bcmul($value, '-1');
}
$letter = $positive ? 'p' : 'n';

$prefix = $suffix = $cprefix = $csuffix = $signal = '';

$signal = $positive ? $locale['positive_sign'] : $locale['negative_sign'];

if ($locale["{$letter}_sign_posn"] == 1 && $flags['usesignal'] == '+')
$prefix = $signal;
elseif ($locale["{$letter}_sign_posn"] == 2 && $flags['usesignal'] == '+')
$suffix = $signal;
elseif ($locale["{$letter}_sign_posn"] == 3 && $flags['usesignal'] == '+')
$cprefix = $signal;
elseif ($locale["{$letter}_sign_posn"] == 4 && $flags['usesignal'] == '+')
$csuffix = $signal;
elseif ($flags['usesignal'] == '(' || $locale["{$letter}_sign_posn"] == 0) {
$prefix = '(';
$suffix = ')';

}
if (!$flags['nosimbol']) {
$currency = $cprefix .
($conversion == 'i' ? $locale['int_curr_symbol'] : $locale['currency_symbol']) .
$csuffix;
} else {
$currency = '';
}
$space = $locale["{$letter}_sep_by_space"] ? ' ' : '';

$value = format::number($value, $right, $locale['mon_decimal_point'],
$flags['nogroup'] ? '' : $locale['mon_thousands_sep']);

$value = @explode($locale['mon_decimal_point'], $value);

$n = strlen($prefix) + strlen($currency) + strlen($value[0]);
if ($left > 0 && $left > $n) {
$value[0] = str_repeat($flags['fillchar'], $left - $n) . $value[0];
}
$value = implode($locale['mon_decimal_point'], $value);
if ($locale["{$letter}_cs_precedes"]) {
$value = $prefix . $currency . $space . $value . $suffix;
} else {
$value = $prefix . $value . $space . $currency . $suffix;
}
if ($width > 0) {
$value = str_pad($value, $width, $flags['fillchar'], $flags['isleft'] ?
STR_PAD_RIGHT : STR_PAD_LEFT);
}

$format = str_replace($fmatch[0], $value, $format);
}
return $format;
}

function number ($number , $decimals = 2 , $dec_point = '.' , $sep = ',', $group=3 ){
// Arbitrary-precision number formatting:
// Takes plain-format, arbitrary-length decimal string (eg: '123456789123456789.123456').
// Takes the same parameters as PHP's native number_format plus a flexible 'grouping' parameter.
// WARNINGS: Truncates -- does not round; not inherently locale-aware

$num = (string) $number;
if (strpos($num, '.')) $num = substr($num, 0, (strpos($num, '.') + 1 + $decimals)); // truncate
$num = explode('.',$num);
while (strlen($num[0]) % $group) $num[0]= ' '.$num[0];
$num[0] = str_split($num[0],$group);
$num[0] = join($sep[0],$num[0]);
$num[0] = trim($num[0]);
$num = join($dec_point[0],$num);

return $num;
}
}

Tests:

 setlocale(LC_MONETARY, 'en_ZW'); // pick your favorite hyperinflated currency
$string = '123456789123456789.123456';

echo "original string: " .
$string . "<br>";
// 123456789123456789.123456
echo "float cast - " .
((float) $string) . "<br>";
// 1.23456789123E+17
echo "number_format original: " .
number_format($string, 4) . "<br>";
// 123,456,789,123,456,768.0000
echo "number_format new: " .
format::number($string, 4) . "<br>";
// 123,456,789,123,456,789.1234
echo "money_format original: " .
money_format('%n', $string) . "<br>";
// Z$ 123,456,789,123,456,784.00
echo "money_format new: " .
format::money('%n',$string) . "<br>";
// Z$ 123,456,789,123,456,789.12


Related Topics



Leave a reply



Submit