As this question has been viewed many times, I've put together a function that may be useful to others who find this question. The following is a script containing some test values, the function currencyToDecimal()
, and then a bit of code to run and display the tests. You only need the function itself.
If you have other test cases that do not pass, please let me know so we can adapt this.
<?php
$testValues = [
'22,50 €',
'22 €',
'22€',
'$22.50',
'$22',
'$0.50¢',
'$22 000 000.50',
'22 000 000,50 €',
'22.000.000,50 €',
];
/**
* Convert Currency String to Decimal
*
* Attempts to support international currency formats by first converting them
* to a standardized format PHP can process consistently.
*
* First, per the SI/ISO 31-0 standard, there are several delimiting options
* for the integer portion (before the radix) that allow for easier reading. We need
* to convert this portion to an integer without readability delimiters.
*
* Second, we need to convert the radix (decimal separator) to a "point" or
* "period" symbol.
*
* Finally, we strip unwanted characters and convert to float.
*
* @see https://en.wikipedia.org/wiki/Decimal_separator
* @see https://en.wikipedia.org/wiki/ISO_31-0
* @see https://docs.oracle.com/cd/E19455-01/806-0169/overview-9/index.html
*/
function currencyToDecimal($value) {
// Ensure string does not have leading/trailing spaces
$value = trim($value);
/**
* Standardize readability delimiters
*****************************************************/
// Space used as thousands separator between digits
$value = preg_replace('/(\d)(\s)(\d)/', '$1$3', $value);
// Decimal used as delimiter when comma used as radix
if (stristr($value, '.') && stristr($value, ',')) {
// Ensure last period is BEFORE first comma
if (strrpos($value, '.') < strpos($value, ',')) {
$value = str_replace('.', '', $value);
}
}
// Comma used as delimiter when decimal used as radix
if (stristr($value, ',') && stristr($value, '.')) {
// Ensure last period is BEFORE first comma
if (strrpos($value, ',') < strpos($value, '.')) {
$value = str_replace(',', '', $value);
}
}
/**
* Standardize radix (decimal separator)
*****************************************************/
// Possible radix options
$radixOptions = [',', ' '];
// Convert comma radix to "point" or "period"
$value = str_replace(',', '.', $value);
/**
* Strip non-numeric and non-radix characters
*****************************************************/
// Remove other symbols like currency characters
$value = preg_replace('/[^\d\.]/', '', $value);
/**
* Convert to float value
*****************************************************/
// String to float first before formatting
$value = floatval($value);
/**
* Give final value
*****************************************************/
return $value;
}
// Run tests through function
echo("ORIGINAL => DECIMAL => DATA TYPE\n");
echo("*********************************************\n");
foreach ($testValues as $value) {
// Run function on test value
$result = currencyToDecimal($value);
// Determine data type. NOTE: Per docs, "double" will be
// returned for a "float" value.
$type = gettype($result);
if ($type === "double") {
$type = "float";
}
// Output [Original] => [Decimal] => [Data Type]
echo("$value => $result => $type\n");
}
The output is as follows:

ORIGINAL => DECIMAL => DATA TYPE
*********************************************
22,50 € => 22.5 => float
22 € => 22 => float
22€ => 22 => float
$22.50 => 22.5 => float
$22 => 22 => float
$0.50¢ => 0.5 => float
$22 000 000.50 => 22000000.5 => float
22 000 000,50 € => 22000000.5 => float
22.000.000,50 € => 22000000.5 => float
References:
https://en.wikipedia.org/wiki/Decimal_separator
https://en.wikipedia.org/wiki/ISO_31-0
https://docs.oracle.com/cd/E19455-01/806-0169/overview-9/index.html