moneyphp/money
PHP library for handling money and currencies safely. Provides immutable Money and Currency value objects, arithmetic with proper rounding, comparisons, formatting, and allocation. Avoid floating-point errors in financial calculations; works well with PHP and frameworks like Laravel.
composer require moneyphp/money.Money object using minor units (e.g., cents for USD):
use Money\Money;
$tenEuros = new Money(1000, new Currency('EUR')); // 10.00 EUR
$total = $tenEuros->add(new Money(500, new Currency('EUR'))); // 15.00 EUR
IntlFormatter):
use Money\Formatter\IntlMoneyFormatter;
$formatter = new IntlMoneyFormatter(new Locale('en_US'));
echo $formatter->format($total); // "€15.00"
First use case: Replace float-based amounts in invoices or cart calculations to guarantee accuracy and prevent rounding errors.
Money in value objects within your domain layer (e.g., ProductPrice, CartTotal).Money with an explicit Currency object (never rely on implicit currency context).add(), subtract(), multiply(), and divide()—they return new instances, enabling safe functional-style chains:
$priceWithTax = $originalPrice
->multiply(1.2, Money::ROUND_HALF_UP)
->add(new Money(0, $originalPrice->getCurrency())); // tax buffer
IntlMoneyFormatter (via ext-intl) for localization.MoneyFormatterInterface to build custom formatters for APIs (e.g., JSON with amount_minor_units + currency_code).MoneyParser (e.g., IntlMoneyParser) to convert localized strings back to Money:
$parsed = $parser->parse('€15,00', new Currency('EUR')); // 1500 minor units
FractionalMoneyFactory for custom minor-unit logic (e.g., jPY, which uses 1-yen units but requires rounding).Money expects amounts in minor units (e.g., 100 for $1.00 USD). Never pass major units directly.divide() and multiply() require rounding strategies (e.g., Money::ROUND_HALF_UP). Default is Money::ROUND_HALF_UP, but mismatched rounding can cause subtle drift.Currency is strict—'usd' (lowercase) is invalid; use 'USD' (uppercase ISO 4217).IntlMoneyFormatter requires ext-intl and correct locale/currency configuration. Test with en_US, de_DE, and ja_JP to catch region-specific formatting issues.equals() (checks amount + currency), not == or ===.Money::zero($currency) over new Money(0, $currency) for clarity and consistency.Money is serializable, but avoid storing raw Money objects in sessions/database—store ['amount' => $m->getAmount(), 'currency' => $m->getCurrency()->getCode()] instead.How can I help you explore Laravel packages today?