How to Format a Number to a Dollar Amount in PHP

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');

Print Currency Number Format in PHP

The easiest answer is number_format().

echo "$ ".number_format($value, 2);

If you want your application to be able to work with multiple currencies and locale-aware formatting (1.000,00 for some of us Europeans for example), it becomes a bit more complex.

There is money_format() but it doesn't work on Windows and relies on setlocale(), which is rubbish in my opinion, because it requires the installation of (arbitrarily named) locale packages on server side.

If you want to seriously internationalize your application, consider using a full-blown internationalization library like Zend Framework's Zend_Locale and Zend_Currency.

PHP money format add decimal and comma when needed

It looks like your variable is in cents, so divide it by 100

echo number_format((247936 / 100), 2, '.', ',');

Output is: 2,479.36

How to format number to currency but don't show the symbol?

To keep it easy MultiSuperFreaks answer is the most common. The function number_format is not deprecated in any way.

If you want to use the intl extension and the NumberFormatter class, you can go like ...

$formatter = new NumberFormatter('en_GB', NumberFormatter::DECIMAL);
$formatter->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, 2);
var_dump($formatter->format(23)); // string(5) "23.00"

Just do not use the NumberFormatter::CURRENCY type. Instead use the NumberFormatter::DECIMAL type when instanciating the NumberFormatter class and then set the attribute for minimal 2 fraction digits.

Number formatting (Money) in PHP

Using brick/money (disclaimer: I'm the author):

use Brick\Money\Money;

// Instantiating from a decimal amount

$money = Money::of('67.95', 'GBP');
echo $money->formatTo('en_GB'); // £67.95

// Instantiating from a minor amount (cents)

$money = Money::ofMinor(6795, 'GBP');
echo $money->formatTo('en_GB'); // £67.95

Format money number_format PHP

As added background information based on my earlier comments, in case you were having trouble separating all the inter-related concerns, and putting all the pieces together, (i don't know if you are or not); Here is some code i've used in the past solving a similar issue. I've adjusted it based on your datamodel/code and added some comments:


Personally, since keeping half the currency information in the database and the other half in code seems messy, i would add 4 columns to your monedas database table; namely (in the case of 'Ecuador' for example):

`currency_symbol`     => '$'
`decimal_separator` => '.'
`thousands_separator` => ','
`decimals` => 2

Next you want to decide what datatype you use for price values in PHP.
I'm guessing they are DECIMALs inside your database, in which case you would either use strings ('65.99') or floats (65.99) in PHP; generally string is prefered as it doesn't suffer from all the oddities that floating point numbers bring to the table.

Alternatively, you could choose to store prices in cents in your database, which would allow you to use INTEGERs (6599) in both the database and in PHP.

Lets assume you use DECIMAL in your database, and string in PHP; that way you can use the PHP BCMath functions to perform calculations reliably.
Lets also assume that all prices in your database always represent the same currency (eg: your business's local currency, lets assume its EUR).


Since prices are a complex value in your webshop-style application, you'll want a simple value class to define them.

class Price {
private $value;

public function __construct($value) {
$value = trim((string) $value);
if (!is_numeric($value) || preg_match('#^(\-)?([0-9]+)(\.[0-9]{1,2})?$#D', $value) !== 1) throw Exception('Invalid price value');
$this->value = $value;
}

public function getRawValue() {
return $this->value;
}

// When printing a price (using echo for example), print it in its converted form (defined later)
public function __toString() {
return PriceLocalization::displayLocalPrice( $this );
}
}

Next, you want an object that holds (or caches) all the information about all currencies:

class Currencies {
protected static $data = null;

protected static function pullData() {
if (is_null(static::$data)) {
$data = [];
// Pull the currency/priceconversion info from the DB
$rows = run_your_dbquery('SELECT * FROM `monera`');
foreach ($rows as $row) {
$row['id_moneda'] = (int) $row['id_moneda'];
$row['decimals'] = (int) $row['decimals'];
$data[( $row['id_moneda'] )] = $row;
}
// Cache the data incase we have to do more conversions on the current page
static::$data = $data;
}
return static::$data;
}

// Returns the entire table of currency/priceconversion info from the DB
public static function getAll() {
return static::pullData();
}

// Returns one record out of the table of currency/priceconversion info (or exception if invalid)
public static function getSpecific($id) {
$data = static::pullData();
if (array_key_exists($id, $data)) return $data[$id];
throw new Exception('Bad input');
}
}

And another object that deals with the user being able to select a currency sessionwide

class UserCurrencySelection {

// store the users choice in $_COOKIE or $_SESSION or the like (used by your currency-selection selectbox)
public static function setUserPreference($choice) {
$_SESSION['currencychoice'] = $choice;
return true;
}

// read the raw value from $_COOKIE or $_SESSION or the like (if any)
public static function getUserPreference() {
return ($_SESSION['currencychoice'] ?? null);
}

// get either the active currency's record (if any), or otherwise the default record (throw exception if neither exists)
public static function getActive() {
try {
if ($current = static::getUserPreference()) {
return Currencies::getSpecific( $current );
}
} catch (Exception $e) {}
return Currencies::getSpecific( 5 ); // <-- the id of the "default" currency (in this case 5 = EUR)
}
}

And finally, the class that actually ties everything together

class PriceLocalization {

// display a specific price adjusted to the -active- currency (with the default currency as fallback)
public static function displayLocalPrice(Price $price, array $style=[]) {
$currencyinfo = UserCurrencySelection::getActive();
return static::displayPriceAs($price, $currencyinfo, $style);
}

// display a specific price adjusted to a -specific- currency (eg: id=3 gives colombian price)
public static function displayPriceInCurrency(Price $price, $id, array $style=[]) {
$currencyinfo = Currencies::getSpecific( $id );
return static::displayPriceAs($price, $currencyinfo, $style);
}

// perform the actual conversion and formatting
protected static function displayPriceAs(Price $price, array $currencyinfo, array $style=[]) {
/* $currencyinfo = [
'id_monera' => 4,
'moneda' => 'USD',
'pais' => 'Ecuador',
'ido' => 'EC',
'cambio' => '1.13',
'impuesto' => '12',
'currency_symbol' => '$',
'decimal_separator' => '.',
'thousands_separator' => ',',
'decimals' => 2,
]; */
// the original price:
$value_src = $price->getRawValue();
// Multiply the original price with the conversion rate (`cambio`) to adjust it to this currency (giving us the pre-tax price)
$value_excl = bcmul($value_src, $currencyinfo['cambio']);
// Calculate the tax, by multiplying the adjusted price with the taxrate (`impuesto`*0.01 to adjust for it being a percentage)
$tax = bcmul($value_excl, bcmul('0.01', $currencyinfo['impuesto']));
// Add the tax to the price to get the "price including tax"
$value_incl = bcadd($value_excl, $tax);
// Decide which of the values you want to display (including or excluding tax)
$value = $value_incl;
// Decide what we want to add before/after the numeric part of the price (the html-encoded version of the currency symbol)
$label_prefix = htmlentities( $currencyinfo['currency_symbol'] . ' ');
$label_suffix = ''; // or: htmlentities( ' ' . $currencyinfo['moneda']);
// Change the number into human readable form
$label = number_format((float) $value, $currencyinfo['decimals'], $currencyinfo['decimal_separator'], $currencyinfo['thousands_separator']);
// Convert that into html
$label = htmlentities($label);
// Define some CSS classes to allow for styling
$classes_prefix = 'p';
$classes_number = 'v';
$classes_suffix = 's';
$classes_full = 'price';
// Now assemble all the pieces
$html_prefix = sprintf('<span class="%s">%s</span>', htmlentities($classes_prefix), $label_prefix);
$html_number = sprintf('<span class="%s">%s</span>', htmlentities($classes_number), $label);
$html_suffix = sprintf('<span class="%s">%s</span>', htmlentities($classes_suffix), $label_suffix);
$html_full = sprintf('<span class="%s">%s%s%s</span>', htmlentities($classes_full), $html_prefix, $html_number, $html_suffix );
// Done
return $html_full;
}
}

That's the gist of it.

You can use the $style argument that's available on each of the PriceLocalization methods to pass arbitrary information along to displayPriceAs. Based on that information you could change the way that function assembles its output. For example, you could check if $style['include_tax'] is set to true/false, and ifso adjust accordingly:

$value = (($style['include_tax'] ?? true) ? $value_incl : $value_excl);

You could style prices with:

.price   { background-color: #EEE; }
.price.p { color: red; font-weight: bold; }
.price.v { color: green; font-family: courier; }
.price.s { color: blue; font-weight: bold; }

And you could also use the $style argument above, to introduce additional classes (in specific cases).


It may also be worth setting bcscale(15); in your application, to ensure the math is done in a way that cannot result in lost partial pennies.


ps: haven't tested the code after adapting it to your code/datamodel, so it is possible i made a typo somewhere.

Best practice to sum and format numbers to dollar values with 2 decimal points?

To format a number to en_US currency format you can create a NumberFormatter object like this:

$oNumberFormatter = new NumberFormatter('en_US', NumberFormatter::CURRENCY);

In this instance prices will be formatted up to normal rules for the given locale; for instance $9.95 for 'en_US` or € 9,95 for 'nl_NL'


If you want a specific ICU Decimal format you could use:

$oNumberFormatter = new NumberFormatter('en_US', NumberFormatter::PATTERN_DECIMAL, '¤ #,##0.00');

The currency symbol (¤) in the format will automatically be converted, when echoed out, to the correct symbol specified by the locale string; so for 'en_US' the dollar symbol ($) will be used - for 'nl_NL' the Euro () and so on.


Either way, in your product display loop, to display the correctly formatted product price, you need only (assuming your product price here is $price) use:

<?= $oNumberFormatter->format( (float) $price); ?>

... and for your free shipping insert:

<?= !$shipping ? "<span class=\"free\">Free Shipping</span>" : $oNumberFormatter->format( (float) $shipping ); ?>

Full details on the NumberFormatter class are at: http://php.net/manual/en/class.numberformatter.php


Just an edit to answer the question in the comments

Ok, thanks. can you explain what you did with the shipping part? I
didn't understand how that format is working. also, how to insert a
dollar sign if for the time being I will use Free Shipping" : number_format((float)$shipping,
2, '.', ''); ?> ?

<?= is shorthand for <?php echo

I'm just using a ternary operator: http://php.net/manual/en/language.operators.comparison.php (scroll down the page a little) - it's just a sort of shorthand for directly assigning a value based on a sort of if (?) else (:) notation:

!$shipping equates to $shipping == false which equates to $shipping == 0 since PHP is loosely typed, so:

<?= !$shipping ? "<span class=\"free\">Free Shipping</span>" : $oNumberFormatter->format( (float) $shipping ); ?>

... is equivalent to ...

<?php
if($shipping == 0) {
echo "<span class=\"free\">Free Shipping</span>";
}
else {
echo $oNumberFormatter->format( (float) $shipping );
}
?>

And for literally outputting a $ string... just use a non-interpolated string literal. PHP has 2 types of string literal (well, 4 with heredoc syntaxes) but essentially an interpolated string is enclosed in double quotes and will parse variables.

<?php
$sWord = "BADGERS";
echo "I like $sWord";
?>

Results in I like BADGERS

Whereas a non-interpolated string (enclosed in apostrophes) will treat $ literally - it won't interpolate variables:

<?php
$sWord = "BADGERS";
echo 'I like $sWord';
?>

Results in I like $sWord literally.

So you can echo out your currency value, with a prefixed dollar sign, like so:

echo '$' . number_format( (float) $shipping, 2, '.', '');

How to convert decimal number to words (money format) using PHP?

There's a PEAR library that can do this.

EDIT

Or you can, at the end of your code, do this

echo $test . ' cents';

How to format numbers as currency strings

Ok, based on what you said, I'm using this:

var DecimalSeparator = Number("1.2").toLocaleString().substr(1,1);

var AmountWithCommas = Amount.toLocaleString();
var arParts = String(AmountWithCommas).split(DecimalSeparator);
var intPart = arParts[0];
var decPart = (arParts.length > 1 ? arParts[1] : '');
decPart = (decPart + '00').substr(0,2);

return '£ ' + intPart + DecimalSeparator + decPart;

I'm open to improvement suggestions (I'd prefer not to include YUI just to do this :-) )

I already know I should be detecting the "." instead of just using it as the decimal separator...



Related Topics



Leave a reply



Submit