Handling monetary values in PHP, or any programming language for that matter, requires careful attention. This is because accuracy and precision are of the utmost importance when dealing with money. In this article, we will delve into how to typecast and handle currency/money data in PHP.
If you're interested, we also have an article on how to store money/currency in your database.
Floating-Point Numbers
In PHP, one might be inclined to use float to represent monetary values because it can hold decimal values. However, using floating-point numbers to represent currency can lead to precision issues.
Here's a small example to illustrate this point:
$amount1 = 1.03;
$amount2 = 0.42;
echo $amount1 - $amount2; // Outputs 0.6100000000000001
In the example above, the expected result is 0.61. However, due to the imprecise nature of floating-point arithmetic, the result deviates from the expectation.
String
If you fetch money data from a database, it often arrives as a string. This format can be beneficial to maintain precision during operations.
$amount1 = "1.03";
$amount2 = "0.42";
echo bcsub($amount1, $amount2, 2); // Outputs 0.61
Here, we use the bcsub
function from PHP's BCMath extension. This function subtracts one arbitrary precision number from another and maintains the precision you specify. This method gives us the correct output.
Integer
A popular and recommended approach is to handle money as integers, in terms of the smallest unit of currency (cents, pence, etc.).
$amount1 = 103; // $1.03
$amount2 = 42; // $0.42
echo ($amount1 - $amount2) / 100; // Outputs 0.61
In this approach, you store the values in cents. All the arithmetic operations are performed in cents and then converted back to dollar format by dividing by 100. This way, precision is maintained throughout.
Using Money Libraries
Another alternative to handle money/currency data in PHP is to use libraries specifically designed for this purpose. Libraries such as moneyphp/money provide features to make it easier and safer to store and perform calculations with money.
use Money\Currency;
use Money\Money;
$fiveEur = new Money(500, new Currency('EUR'));
In the above example, the Money library uses integer math internally, ensuring precision throughout its operations.
Conclusion
To recap, handling currency/money data in PHP can be a tricky task due to precision issues if you use floating-point numbers. It's typically better to handle currency as strings using PHP's BCMath extension functions or as integers in terms of cents. Additionally, you can use dedicated libraries to handle money, which ensure precision and offer a more convenient API for monetary calculations.
Remember that you should also ensure you're properly storing your money/currency, and that the transfer from database to code and back again doesn't transform the data in any way. Some frameworks have tools in place to help this process.
Interested in proving your knowledge of this topic? Take the PHP Fundamentals certification.
PHP Fundamentals
Covering the required knowledge to create and build web applications in PHP.
$99