Skip to content

LeaflowNET/ext-money

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ext-money

License: MIT PHP 8.4+

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.

Why another money library?

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.

Installation

composer require leaflownet/ext-money

Requires PHP 8.4+ (uses the BcMath\Number OOP API) and ext-bcmath.

Usage

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 CurrencyMismatchException

Properties

  • Money::$micro — signed 64-bit integer, the amount in 10⁻⁸ units
  • Money::$currency — uppercase ISO-4217-style 3-letter code

Range and overflow

  • Money can 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 exceed PHP_INT_MAX or fall below PHP_INT_MIN.
  • Intermediate computations use arbitrary-precision BcMath\Number, so the guard fires before the result is cast back to int.

License

MIT — see LICENSE.

About

Immutable Money value object with 10^-8 micro precision and BcMath-backed arithmetic.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages