I am trying to format from EURO to Latin American countries. But I can't get all of them to format correctly.
These two lines work fine:
$currencies['ESP'] = array(2, ',', '.'); // Euro
$currencies['USD'] = array(2, '.', ','); // US Dollar
The ones that don't work are these:
Mexico I have $ 1,800,520 Mexican Peso and I want to obtain this result $ 3,698.00
$currencies['MXN'] = array(3, ",", '.'); // México PesoColombia $ 2,097,106.36 Colombian peso and I want to get $ 104,637,255.96
$currencies['COP'] = array(2, ',', '.'); // Colombiano PesoArgentina $ 53,609.02 Argentine peso and I want to get $ 10,490
$currencies['ARS'] = array(2, ',', '.'); // Argentina Peso
Does anyone know what I'm doing wrong? I appreciate any help.
Example of my functions:
/**
* @param self::$curr
* @return string
*/
public static function setCurrency($tipo) {
// Creamos tipo moneda
$tipoMoneda = ($tipo =='') ? self::$curr : $tipo;
$moneda = match ($tipoMoneda) {
'CLF' => "$",
'COP' => "$",
'ARS' => "$",
'USD' => "$",
'EUR' => "€",
'MXN' => "$",
};
return $moneda;
}
/**
* Format price
* @param string
* @param string
*/
public static function toMoney($price,$tipo='') {
$currencies['EUR'] = array(2, ',', '.'); // Euro
$currencies['ESP'] = array(2, ',', '.'); // Euro
$currencies['USD'] = array(2, '.', ','); // US Dollar
$currencies['COP'] = array(2, ',', '.'); // Colombian Peso
$currencies['MXN'] = array(3, ",", '.'); // Mexico Peso
$currencies['CLP'] = array(0, '', '.'); // Chilean Peso
$currencies['ARS'] = array(2, ',', '.'); // Argentina Peso
if ($tipo == '') :
$money_format = number_format($price, ...$currencies[self::$curr]) . ' ' . self::setCurrency($tipo);
else:
$money_format = self::setCurrency($tipo) . number_format($price, ...$currencies[$tipo]);
endif;
return $money_format;
}
EDIT: The exchange rate i get it from the DB

/**
* Calcular TAXES about original price base
* @param string
* @return string
*/
public static function CalcIva($valor, $arr =[]) {
// Get default IVA o by (USD-MXN) (COOKIE)
$getIva = self::$defaultIva;
// Price original
$price = $valor;
// Get taxes
$iva = ($getIva / 100) * $price;
// Sum taxes to base price
$precio = $price + $iva;
// On this line if $arr is not null i calculate 1.13 or some else x price
if ($arr != null) :
// Calcul exchange rate (example: 1.13 * 20)
$precio = $arr['cambio'] * $price;
endif;
// Price
return $precio;
}
To set the cookie i do it on JS
/**
* Select money (header)
*/
let moneda = document.getElementById('slc-moneda');
moneda.addEventListener('change', function (e) {
// Get value option
let tipo = this.value;
// Not null
if (tipo != 0) {
// Value default, delete cookie
if (tipo == 'EUR-ES') {
// Eliminamos cookie, usamos configuracion por defecto
delCookie('moneda');
location.reload()
// Set cookie - new money format
} else {
setCookie('moneda', tipo, 365)
location.reload()
}
}
e.preventDefault()
})
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
monedasdatabase table; namely (in the case of 'Ecuador' for example):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; generallystringis 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
DECIMALin your database, andstringin 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 itsEUR).Since prices are a complex value in your webshop-style application, you'll want a simple value class to define them.
Next, you want an object that holds (or caches) all the information about all currencies:
And another object that deals with the user being able to select a currency sessionwide
And finally, the class that actually ties everything together
That's the gist of it.
You can use the
$styleargument that's available on each of thePriceLocalizationmethods to pass arbitrary information along todisplayPriceAs. 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 totrue/false, and ifso adjust accordingly:You could style prices with:
And you could also use the
$styleargument 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.