Php – How to add currency strings (non-standardized input) together in PHP

php

I have a form in which people will be entering dollar values.

Possible inputs:
$999,999,999.99
999,999,999.99
999999999
99,999
$99,999

The user can enter a dollar value however they wish. I want to read the inputs as doubles so I can total them.

I tried just typecasting the strings to doubles but that didn't work. Total just equals 50 when it is output:

$string1 = "$50,000";
$string2 = "$50000";
$string3 = "50,000";
$total = (double)$string1 + (double)$string2 + (double)$string3;
echo $total;

Best Solution

A regex won't convert your string into a number. I would suggest that you use a regex to validate the field (confirm that it fits one of your allowed formats), and then just loop over the string, discarding all non-digit and non-period characters. If you don't care about validation, you could skip the first step. The second step will still strip it down to digits and periods only.

By the way, you cannot safely use floats when calculating currency values. You will lose precision, and very possibly end up with totals that do not exactly match the inputs.

Update: Here are two functions you could use to verify your input and to convert it into a decimal-point representation.

function validateCurrency($string)
{
    return preg_match('/^\$?(\d{1,3})(,\d{3})*(.\d{2})?$/', $string) ||
           preg_match('/^\$?\d+(.\d{2})?$/', $string);
}

function makeCurrency($string)
{
    $newstring = "";

    $array = str_split($string);
    foreach($array as $char)
    {
        if (($char >= '0' && $char <= '9') || $char == '.')
        {
            $newstring .= $char;
        }
    }

    return $newstring;
}

The first function will match the bulk of currency formats you can expect "$99", "99,999.00", etc. It will not match ".00" or "99.", nor will it match most European-style numbers (99.999,00). Use this on your original string to verify that it is a valid currency string.

The second function will just strip out everything except digits and decimal points. Note that by itself it may still return invalid strings (e.g. "", "....", and "abc" come out as "", "....", and ""). Use this to eliminate extraneous commas once the string is validated, or possibly use this by itself if you want to skip validation.