brick / money

A money and currency library for PHP
MIT License
1.65k stars 102 forks source link

Persisting into database #16

Closed mtangoo closed 6 years ago

mtangoo commented 6 years ago

Hi, Thank you for the library. I was reading the doc and its comprehensive except it does not provide any recommendation as to what should be the field type (database column data type that can work better with library). This will help avert confusion as reading the answers on the internet ends up confusing newbees. Also comment on fields like Postgresql Money data type would be helpful.

Cheers!

BenMorel commented 6 years ago

Hi, this could be a nice thing to add to the doc indeed.

For the time being, I can only tell you that I personally store my monies in the database as an integer representing the amount in minor units (cents), and optionally a CHAR(3) for the currency if the application uses multiple currencies (otherwise the currency is hardcoded in the app).

You can get the amount in minor units this way, as an integer:

$money->getMinorAmount()->toInt();

And you can retrieve a Money from an integer stored in the database using:

Money::ofMinor($integerAmount, 'USD');

I cannot comment on the money data type, as I don't use Postgresql. But I will surely look at it if I add this doc later on!

mtangoo commented 6 years ago

Thanks for the quick response. That cleared a lot of fogs. I have one more question though.

I was thinking about using NUMERIC(15, 6) to store full data. What do think of performance given you are the author and knows internals of the library?

mtangoo commented 6 years ago

I will close this for now, since main issue is solved. If you get time you can address the other one too! Thank you!

BenMorel commented 6 years ago

The problem with NUMERIC is not performance (NUMERIC and INTEGER should perform equally well), it is that the scale is fixed. This is OK if you're dealing with a single currency, but as soon as you want support for multiple currencies, this can become a problem as they don't all have 2 fraction digits. JPY for example has 0 fraction digits, while TND has 3 digits. You can use a NUMERIC that has the largest scale, of course, but my preference is to deal with integers here, and the scale is implied by the currency.

mtangoo commented 6 years ago

I see! Yours is the most logical way. Thank you for your time!

BenMorel commented 4 years ago

Now documented 😉

https://github.com/brick/money#storing-the-monies-in-the-database