NumberFormatter generate unbreakable space - php

I try to put a formated currency input from php as value of an input,
$format = numfmt_create( 'fr_FR', NumberFormatter::CURRENCY);
$datavalue = numfmt_format_currency($format, $data['value'], 'EUR');
It works, but the result contain unbreakable space caracter like so
value='10,0 €'
That lead to mess up with my design, I didn't found how to remove it yet
Already tried :
str_replace(' ', " ", $datavalue);

Run the result through html_entity_decode() then perform your str_replace(' ', '', $datavalue);
That class/function prefers an integer be passed to it, so you need to clean up your data before you ever get to the function.

You can use numberFormatter
example:
$amount = '12345.67';
$formatter = new NumberFormatter('fr_FR', NumberFormatter::CURRENCY);
echo 'format: ', $formatter->formatCurrency($amount, 'EUR'), PHP_EOL;
//output
12 345,67 €
edit: other method is use this MoneyFormat
example
$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

Related

How to "cut the fluff" out from PHP's NumberFormatter to display a "compact" money sum for a spreadsheet context? [duplicate]

I'm trying to format revenue totals as grabbed from a db, and using php's NumberFormatter class, with the formatCurrency method.
However, I do not want to print out the actual € / Euro symbol with this. I just want the plain number, with comma's and decimal points.
Example;
1234.56 should be formatted as 1,234.56
The current output is giving €1,234.56.
Code I'm using:
$array['total_revenue'] = $this
->db
->query($sql)
->row_array()['SUM( booking_total )'];
$formatter = new NumberFormatter('en_GB', NumberFormatter::CURRENCY);
echo $formatter->formatCurrency($array['total_revenue'], 'EUR') . PHP_EOL;
Would anyone have any ideas on how I can fix this up to remove the euro symbol?
You should use setSymbol() function:
$formatter = new NumberFormatter('en_GB', NumberFormatter::CURRENCY);
$formatter->setSymbol(NumberFormatter::CURRENCY_SYMBOL, '');
echo $formatter->formatCurrency($array['total_revenue'], 'EUR') . PHP_EOL;
I came here because for some reason, $formatter->setSymbol(NumberFormatter::CURRENCY_SYMBOL, ''); was being ignored by $formatter->formatCurrency($array['total_revenue'], 'USD');
To resolve this issue, I found out a solution here.
https://www.php.net/manual/en/numberformatter.setsymbol.php#124153
this could be obvious to some, but setSymbol(NumberFormatter::CURRENCY_SYMBOL, '') doesn't work for formatCurrency - it will simply be ignored...
use NumberFormatter::CURRENCY and $fmt->format(123); to get a currency value with the symbol specified as CURRENCY_SYMBOL (or INTL_CURRENCY_SYMBOL)
i.e
$fmt = new NumberFormatter('de_DE', NumberFormatter::CURRENCY);
$fmt->setSymbol(NumberFormatter::CURRENCY_SYMBOL, '');
$fmt->setAttribute(NumberFormatter::FRACTION_DIGITS, 2);
echo $fmt->format(56868993064.7985);
//Output: 56.868.993.064,80 
A simple regex is a quick fix for your problem. Try;
$actual = $formatter->formatCurrency($array['total_revenue'], 'EUR') . PHP_EOL;
$output = preg_replace( '/[^0-9,"."]/', '', $actual );
echo $output;
Hope this helps
The formatCurrency() method is convenient in that it automatically formats the amount according to the rules of the specified currency. For example, when formatting an amount in Euros, the number should show 2 decimal places. But when formatting an amount in Yen, the number should have no decimals as fractions of Yen do not exist (as far as I know). Other currencies may have 3 or even 4 decimals.
If the goal is to keep all functionality of the formatCurrency() method except for the removal of the currency symbol (or code), then I'd suggest this snippet:
$localeCode = 'en_US';
$currencyCode = 'USD';
$amount = 10000;
$formatter = new \NumberFormatter($localeCode, \NumberFormatter::CURRENCY);
$formatter->setTextAttribute(\NumberFormatter::CURRENCY_CODE, $currencyCode);
$formatter->setSymbol(\NumberFormatter::CURRENCY_SYMBOL, '');
$formatter->format($amount);
Please note that it is necessary to set the currency code BEFORE clearing the currency symbol. Trying to set the currency after clearing the symbol will not work, as setting the currency will automatically load the related symbol.

Removing currency symbol from formatCurrency

I'm trying to format revenue totals as grabbed from a db, and using php's NumberFormatter class, with the formatCurrency method.
However, I do not want to print out the actual € / Euro symbol with this. I just want the plain number, with comma's and decimal points.
Example;
1234.56 should be formatted as 1,234.56
The current output is giving €1,234.56.
Code I'm using:
$array['total_revenue'] = $this
->db
->query($sql)
->row_array()['SUM( booking_total )'];
$formatter = new NumberFormatter('en_GB', NumberFormatter::CURRENCY);
echo $formatter->formatCurrency($array['total_revenue'], 'EUR') . PHP_EOL;
Would anyone have any ideas on how I can fix this up to remove the euro symbol?
You should use setSymbol() function:
$formatter = new NumberFormatter('en_GB', NumberFormatter::CURRENCY);
$formatter->setSymbol(NumberFormatter::CURRENCY_SYMBOL, '');
echo $formatter->formatCurrency($array['total_revenue'], 'EUR') . PHP_EOL;
I came here because for some reason, $formatter->setSymbol(NumberFormatter::CURRENCY_SYMBOL, ''); was being ignored by $formatter->formatCurrency($array['total_revenue'], 'USD');
To resolve this issue, I found out a solution here.
https://www.php.net/manual/en/numberformatter.setsymbol.php#124153
this could be obvious to some, but setSymbol(NumberFormatter::CURRENCY_SYMBOL, '') doesn't work for formatCurrency - it will simply be ignored...
use NumberFormatter::CURRENCY and $fmt->format(123); to get a currency value with the symbol specified as CURRENCY_SYMBOL (or INTL_CURRENCY_SYMBOL)
i.e
$fmt = new NumberFormatter('de_DE', NumberFormatter::CURRENCY);
$fmt->setSymbol(NumberFormatter::CURRENCY_SYMBOL, '');
$fmt->setAttribute(NumberFormatter::FRACTION_DIGITS, 2);
echo $fmt->format(56868993064.7985);
//Output: 56.868.993.064,80 
A simple regex is a quick fix for your problem. Try;
$actual = $formatter->formatCurrency($array['total_revenue'], 'EUR') . PHP_EOL;
$output = preg_replace( '/[^0-9,"."]/', '', $actual );
echo $output;
Hope this helps
The formatCurrency() method is convenient in that it automatically formats the amount according to the rules of the specified currency. For example, when formatting an amount in Euros, the number should show 2 decimal places. But when formatting an amount in Yen, the number should have no decimals as fractions of Yen do not exist (as far as I know). Other currencies may have 3 or even 4 decimals.
If the goal is to keep all functionality of the formatCurrency() method except for the removal of the currency symbol (or code), then I'd suggest this snippet:
$localeCode = 'en_US';
$currencyCode = 'USD';
$amount = 10000;
$formatter = new \NumberFormatter($localeCode, \NumberFormatter::CURRENCY);
$formatter->setTextAttribute(\NumberFormatter::CURRENCY_CODE, $currencyCode);
$formatter->setSymbol(\NumberFormatter::CURRENCY_SYMBOL, '');
$formatter->format($amount);
Please note that it is necessary to set the currency code BEFORE clearing the currency symbol. Trying to set the currency after clearing the symbol will not work, as setting the currency will automatically load the related symbol.

Price formatting for Portuguese

On my website, echo $symbols['currency']; echo $fields['price']; holds a value in US currency format and it outputs R$19800
and echo $symbols['currency']; echo number_format($fields['price']); outputs R$19,800
How do I format it to output R$19.800,00 which is Portuguese price formatting?
I tried
echo $symbols['currency'];
setlocale(LC_MONETARY, 'it_IT');
echo money_format('%.2n', $fields['price']);
and it outputs R$EUR 19.800,00 which is corrent, but Im finding it hard to remove EUR from printing. Thanks a lot.
Simply use the PHP function str_replace:
$money = money_format('%.2n', $fields['price']);
echo str_replace("EUR", "", $money);
You can do this without locale and str_replace() (which I consider just fixing/hiding something done not correctly) by just using number_format():
echo $symbols['currency'];
echo number_format((float) $fields['price'], 2, ',', '.');

PHP's floatval is not locale aware

I find that PHP's string to float conversion is not locale aware. If I setlocale() to a locale where the decimal point is a comma, floatval fails to parse "3,14". I find this surprising especially since the opposite conversion - float to string - is locale aware and outputs the comma.
<?php
setlocale(LC_ALL, "Norwegian", "no");
$localeconv = localeconv();
echo "decimal_point is `" . $localeconv['decimal_point'] . "'<br/>";
print "float to string: " . 3.14 . "<br/>"; // <-- Outputs "3,14" CORRECT
print "string to float: " . floatval("3,14"); // <-- Outputs "3" INCORRECT
?>
The output I get is the following:
decimal_point is `,'
float to string: 3,14
string to float: 3
This is with PHP 5.3.6 on Windows. Is this the intended behaviour? Does PHP on Unix give the same result?
There is a locale aware function in The PHP Manual
<?php
function ParseFloat($floatString){
$LocaleInfo = localeconv();
$floatString = str_replace($LocaleInfo["mon_thousands_sep"] , "", $floatString);
$floatString = str_replace($LocaleInfo["mon_decimal_point"] , ".", $floatString);
return floatval($floatString);
}
?>
This is safer than simply replacing commas with dots as that would break things for some locales.

Str_replace for multiple items

I remember doing this before, but can't find the code. I use str_replace to replace one character like this: str_replace(':', ' ', $string); but I want to replace all the following characters \/:*?"<>|, without doing a str_replace for each.
Like this:
str_replace(array(':', '\\', '/', '*'), ' ', $string);
Or, in modern PHP (anything from 5.4 onwards), the slighty less wordy:
str_replace([':', '\\', '/', '*'], ' ', $string);
str_replace() can take an array, so you could do:
$new_str = str_replace(str_split('\\/:*?"<>|'), ' ', $string);
Alternatively you could use preg_replace():
$new_str = preg_replace('~[\\\\/:*?"<>|]~', ' ', $string);
For example, if you want to replace search1 with replace1 and search2 with replace2 then following code will work:
print str_replace(
array("search1","search2"),
array("replace1", "replace2"),
"search1 search2"
);
// Output: replace1 replace2
str_replace(
array("search","items"),
array("replace", "items"),
$string
);
If you're only replacing single characters, you should use strtr()
You could use preg_replace(). The following example can be run using command line php:
<?php
$s1 = "the string \\/:*?\"<>|";
$s2 = preg_replace("^[\\\\/:\*\?\"<>\|]^", " ", $s1) ;
echo "\n\$s2: \"" . $s2 . "\"\n";
?>
Output:
$s2: "the string "
I had a situation whereby I had to replace the HTML tags with two different replacement results.
$trades = "<li>Sprinkler and Fire Protection Installer</li>
<li>Steamfitter </li>
<li>Terrazzo, Tile and Marble Setter</li>";
$s1 = str_replace('<li>', '"', $trades);
$s2 = str_replace('</li>', '",', $s1);
echo $s2;
result
"Sprinkler and Fire Protection Installer", "Steamfitter ", "Terrazzo, Tile and Marble Setter",
I guess you are looking after this:
// example
private const TEMPLATE = __DIR__.'/Resources/{type}_{language}.json';
...
public function templateFor(string $type, string $language): string
{
return \str_replace(['{type}', '{language}'], [$type, $language], self::TEMPLATE);
}
In my use case, I parameterized some fields in an HTML document, and once I load these fields I match and replace them using the str_replace method.
<?php echo str_replace(array("{{client_name}}", "{{client_testing}}"), array('client_company_name', 'test'), 'html_document'); ?>

Categories