Recently I had the chance to integrate the Money library into a Symfony app with Doctrine. It looked as a pleasant learning experience in the beginning, but I swiftly found myself dealing with complexity here and there, so I said, «Let’s share some feedback with those guys behind the PHP Money library.»
And I ended up opening a discussion here. By the way, don’t get me wrong, Symfony, Doctrine and Money, they all are fantastic free software projects in my opinion.
The thing is that a config file was copied from GitHub and pasted into the app I was working on, and it was already set up for Doctrine to handle
BIGINT by default. The reason being: I guess that many developers out there will use
BIGINT for money with no strong reason behind. But think a bit about it. Why do we need
BIGINT for currency/money in our PHP/MySQL applications? Do we actually need the BC Math extension or the GMP extension?
Today I would like to raise some awareness about a programming principle that in my humble opinion can be beneficial for apps. I am talking about the minimum privilege principle…
The Principle of Minimum Privilege?
Exactly! Applied to writing PHP/MySQL apps dealing with money, it is somewhat of a mindset saying:
BIGINTonly when necessary»
- «Dealing with money is not a necessary condition for using
- «Stay away from libraries processing astronomical numbers, because you don’t need BC Math or GMP«
More specifically, in a context of Symfony + Doctrine + Money library, the principle highlights the cons:
- Doctrine will convert
- This is a tricky issue across different database vendors
- 64-bit machines handle bigints differently than 32-bit machines
- Mapping SQL BIGINT to actual PHP integers is an issue
- And most importantly, by including BC Math and GMP you’re introducing vulnerabilities into your app
Listen to What It Says…
It is all about approaching the app’s design with a simplicity mindset. We want to control complexity, so rather than including this or that library in our projects almost as a habit, we perform a basic analysis first by addressing some questions:
- «What is a realistic max limit for money in my app?»
- «Does my app need to use currencies?»
The answers to them will serve as a guideline for making a decision about how to proceed next.
OK, let’s say we estimated that $10,000,000 is a realistic limit in our app’s domain. We don’t need to care about currencies, and we must process cents; if that is the case, the SQL
DECIMAL type is a simple solution that works OK. More specifically, use
DECIMAL(12,4) if you want to comply with Generally Accepted Accounting Principles (GAAP) rules.
DECIMALis consistent with the app’s domain rules
- The Money library is not included into the app
- BC Math and GMP functions are not included into the app
- As a developer, you simply forget about the arithmetics involved in money
- Doctrine won’t complain about integrating with custom types
- The app’s attack surface is reduced
Applying minimal privilege concepts into your apps will have a positive impact on stability, security and scalability. Of course you are not forced to use the least privilege principle all the time, but I think it is absolutely necessary in many instances. I like it!