Immutable Money value object with 10⁻⁸ micro precision and BcMath-backed
arithmetic. Designed for cloud-billing accounting where per-second rates need
to multiply by per-month durations without losing precision.
| Library | Precision | Approach |
|---|---|---|
moneyphp/money |
ISO 4217 minor unit (e.g. cents) | Per-currency fractionDigits, tied to ISO standard |
brick/money |
Configurable via CustomContext(N) |
Powerful but requires custom currency for non-ISO precision |
leaflownet/ext-money |
Fixed 10⁻⁸ micro | Simple int64-backed VO, BcMath overflow guards, no currency-tied scale |
If you bill by the second and need 0.00016666... CNY/sec × 2_592_000 sec to
round-trip exactly, you want micro precision. ISO minor (cent) silently
collapses to zero in this scenario.
composer require leaflownet/ext-moneyRequires PHP 8.4+ (uses the BcMath\Number OOP API) and ext-bcmath.
use LeaflowNet\Money\Money;
// Constructors
$balance = Money::fromMicro(100_000_000, 'CNY'); // 1.00 CNY
$cents = Money::fromCents(1234, 'USD'); // 12.34 USD
$major = Money::fromMajor(5, 'CNY'); // 5.00 CNY
$zero = Money::zero('CNY'); // 0.00 CNY
// Arithmetic (all go through BcMath\Number with int64 overflow guards)
$total = $balance->add(Money::fromCents(500)); // 1.05 CNY
$diff = $balance->sub(Money::fromMicro(1)); // 0.99999999 CNY
$rate = Money::fromMicro(1_000)->mul(2_592_000); // per-second × seconds-in-month
// Rational multiplication: avoids overflow even when numerator * den exceeds int64
$prorated = $monthly->mulRational(7, 24); // 7 / 24 of monthly
// Comparison
$balance->compare($zero); // -1 / 0 / 1
$balance->isZero(); // false
$balance->isNegative(); // false
$balance->equals($zero); // false
// Display (floors to cents, 10^-2)
$balance->toDisplayCents(); // 100
$balance->toDisplayString(); // "1.00"
// Cross-currency operations throw CurrencyMismatchException
$cny = Money::fromCents(100, 'CNY');
$usd = Money::fromCents(100, 'USD');
$cny->add($usd); // throws CurrencyMismatchExceptionMoney::$micro— signed 64-bit integer, the amount in 10⁻⁸ unitsMoney::$currency— uppercase ISO-4217-style 3-letter code
Moneycan represent any value within signed int64 micro: roughly -92.2 billion to +92.2 billion of the major unit.- All arithmetic throws
InvalidArgumentException("Money overflow: ...")if the result would exceedPHP_INT_MAXor fall belowPHP_INT_MIN. - Intermediate computations use arbitrary-precision
BcMath\Number, so the guard fires before the result is cast back toint.
MIT — see LICENSE.