brick/money
Immutable money & currency library for PHP with exact arithmetic, explicit rounding control, and support for any-sized amounts. Built on brick/math to avoid floating-point errors; works with ISO currencies and integrates well with GMP/BCMath for speed.
float.CashContext for Swiss Franc rounding rules), enabling compliance with region-specific financial regulations.composer require brick/money. No global state or configuration required.protected $price;) with accessors/mutators for serialization/deserialization.JsonSerializable or custom encoders (e.g., Money::getAmount() + Money::getCurrency()).999 for $9.99 USD) to avoid precision loss.CHAR(3) (ISO 4217) or INTEGER (numeric codes).step for CashContext) as JSON or separate columns.0.13.*).bcmath for critical paths.0.10 (PHP 8.1) or 0.8 (PHP 8.0), but note EOL risks.0.1 + 0.2 = 0.30000000000000004) acceptable in your domain?CashContext for CHF) or dynamic scaling (e.g., AutoContext)?Money as minor units + currency code, or serialize the entire object?CashContext with step=5)?RationalMoney could cause memory issues?Money in unit tests, or use a test double library (e.g., mocks-for-php)?Money objects in DTOs (e.g., CreateOrderRequest with Money $amount).Money to JSON via JsonSerializable or custom accessors.DECIMAL or BIGINT (e.g., amount_minor INT, currency CHAR(3)).{ amount: 999, currency: "USD", context: { type: "default" } }).Money objects using igbinary or json_encode for caching order totals.brick/math for conversions).float/int amounts with Money in domain models (e.g., Order, Invoice).// Before
public function calculateTotal(): float { return $this->items->sum('price'); }
// After
public function calculateTotal(): Money {
return $this->items->reduce(
fn (Money $carry, Item $item) => $carry->plus($item->getPrice()),
Money::zero('USD')
);
}
Money objects (e.g., GET /orders/{id} → { "total": { "amount": 999, "currency": "USD" } }).JsonResponse with custom encoders if needed.Schema::table('orders', function (Blueprint $table) {
$table->unsignedBigInteger('total_amount_minor')->default(0);
$table->char('currency', 3)->default('USD');
});
Money::ofMinor().float operations (e.g., LegacyMoney::fromFloat(19.99, 'USD')).Money is serializable via serialize() (PHP’s native mechanism) or JsonSerializable.Money payloads (e.g., OrderCreated with Money $amount).Money in notification data (e.g., OrderPaid email with formatted amount).float amounts with Money in subscription logic.Money fields for search (e.g., filter orders by price range).Money payloads (ensure serialization works).Money usage in specific modules (e.g., e-commerce vs. admin dashboard).Money operations in production (e.g., Xdebug, Blackfire) to identify GMP/BCMath bottlenecks.0.13.*) to avoid unexpected breaking changes.composer why brick/money to audit dependencies.CashContext for CHF with step=5").RoundingMode::Down for cashier drawer reconciliation").USD + EUR).RoundingMode::Up").Money objects are properly serialized/deserialized in queues or caches.Money::getAmount() + Money::getCurrency() for logging/debugging.How can I help you explore Laravel packages today?