PHP doesn't know what "dollars" are. When it sees "$12.00", it doesn't know that the dollar sign is separate, and to treat the rest as a number. As far as PHP is concerned, asking for "$12.00" * 0.05
is no different from asking for "$$$12.00$$$" * 0.05
, or "potato" * 0.05
.
So you have two options:
- Change the form so that the value submitted is only numbers. If it's entered by the user, write some validation code that checks it is just a number, like
if ( ! preg_match('/^\d+\.\d{2}$/', $_POST['amount']) ) { show_wrong_amount_error_message(); }
- Strip the "$" off the front before processing it, using Duncan's suggestion of
$amount = ltrim($_POST['amount'], '$');
or aynba's suggestion of $amount = preg_replace("/[^0-9.-]/", '', $_POST['amount']);
Or you could combine the two: check that it has exactly a dollar sign, a number of dollars, and a number of cents; then discard the dollar sign and carry on:
if ( preg_match('/^\$(\d+\.\d{2})$/', $_POST['amount'], $matched_parts) ) {
$amount = (float)$matched_parts[1];
}
else {
show_wrong_amount_error_message();
}
You should also consider handling money as an integer number of cents, not a floating point number of dollars, because floating point numbers are not precise. So you could adjust the above to give you the amount in cents instead:
if ( preg_match('/^\$(\d+)\.(\d{2})$/', $_POST['amount'], $matched_parts) ) {
$amount_cents = (int)$matched_parts[1] * 100 + (int)$matched_parts[2];
}
else {
show_wrong_amount_error_message();
}