Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice for working with currency values in PHP?

Tags:

types

php

decimal

I need to add, multiply and compare currency values in PHP and need to be sure that it is exact down to a single cent.

One way is to store everything in float, use round before and after each operation and mind machine epsilon when comparing for equality. Quite cumbersome imho.

Another way is to store the whole thing as cents in integer data types, plus remember to convert back and forth anytime I work with the database (mysql, where I use the decimal data type). Inelegant, and many error pitfalls, imho.

Another way is to invent my own "datatype", store all values in strings ("34.12") and create my own mathematical replacement functions. These function would convert the value to integers internally, do the calculation and output the result again a strings. Suprisingly complicated, imho.

My question: what is the best practice for working with currency values in PHP? Thanks!

like image 496
CruftyCraft Avatar asked Sep 29 '10 07:09

CruftyCraft


People also ask

How we operate with currencies in PHP?

As I mentioned above, first we have to check that the two Money objects are the same currency before we add them together. If the two objects are the same currency we can take the value of the current object and the value of the object we want to add to, as well as the currency to create a new Money object.

What datatype is best suited to store currency values?

Which datatype is best suited to store currency values? Explanation: Currency is a numeric information. For monetary calculations, FLOAT and DOUBLE are subject to rounding error and may not be suitable. A DECIMAL(M, 2) type is best suited for it.


2 Answers

As of MySQL v5.0.3, MySQLs DECIMAL datatype stores an exact decimal number, i.e. not an inaccurate floating point representation.

To correctly manipulate precision numbers in PHP use the arbitrary precision math functions. Internally this library manipulates text strings.

Currency is intended to be stored as a decimal number, you can get units of money smaller than cents. You should only round any values when displaying the figures, not during manipulation or storage.

like image 180
Randy the Dev Avatar answered Oct 03 '22 02:10

Randy the Dev


Update 2016:

A couple of years later and hopefully a little bit wiser ;)
Since this answer still receives the occasional up- and down vote I felt the need to revise my answer. I absolutely do not advise storing 'money' as integers anymore. The only true answer is Andrew Dunn's: Use Mysql's DECIMAL type and encapsulate php's bc_* functions in a Currency class.


I will keep my outdated answer here for completeness sake

You should always work with integers. Store the values as ints in your database, use ints to do calculations and when, and only when, you want to print it, convert it to some readable format.

This way you completeley circumvent floating point problems, which, generally, is a big problem when working with money ;)

Edit: One thing worth mentioning: You need to think about precision before you start working this way. As others have pointed out, you might need to work with values smaller than a cent, so you need to do your multiplication/division accordingly. (ie currency * 1000 for a .001 precision)

like image 43
Dennis Haarbrink Avatar answered Oct 03 '22 01:10

Dennis Haarbrink