NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Packagist · #539 most downloaded on Packagist
Money and currency library
Last release 8 days ago
29 Sep 2026
Ships unpredictably
gaps range from 8 days to 5 months
Nearly every release is documented
notes for 45 of 46 stable releases
Nothing withdrawn
no release was ever pulled
9 years old
46 releases · first in 2017
Money::formatToLocale() and MoneyLocaleFormatter would, for some locales, format with root locale data, and break every intl formatter created afterwa
🐛 Bug fix
Money::formatToLocale() and MoneyLocaleFormatter would, for some locales, format with root locale data, and break every intl formatter created afterwards for that locale in the same process (#135 by @tomsommer)Compatibility with brick/math version 1.0
📌 Compatibility
brick/math version 1.0One column per quarter.
The constructors of these exception classes are now @internal :
💥 Breaking changes
@internal:
ExchangeRateProviderExceptionMoneyFormatExceptionMoneyNumberFormatter has been removed; call NumberFormatter::formatCurrency() directly insteadMoney::formatToLocale() and MoneyLocaleFormatter:
MoneyFormatException on older ICU (this is independent of the PHP version)CurrencyDisplay parameter in the second positionMoneyFormatException if the amount cannot be accurately represented as a float, rather than formatting it with wrong digitsMoneyFormatException if the intl extension has no data for the locale's language (e.g. xx_YY), rather than silently formatting in the process default locale$allowWholeNumber parameter of Money::formatToLocale() and MoneyLocaleFormatter has been renamed to $hideFractionIfWhole✨ New features
Money::formatToLocale() and MoneyLocaleFormatter now accept a CurrencyDisplay parameter controlling how the currency is displayed: Symbol (default), NarrowSymbol, Code, Name, or None (amount only)MoneyLocaleFormatter now properly displays custom currencies whose code is not three letters (e.g. USDT, GOLD)Compatibility with brick/math version 0.20
📌 Compatibility
brick/math version 0.20Compatibility with brick/math version 0.19
📌 Compatibility
brick/math version 0.19deprecated class ProviderChain has been removed; use ChainProvider instead
The following breaking changes only affect you if you're using named arguments:
💥 Breaking changes
MoneyBag can no longer be instantiated with new: its constructor is now private; use MoneyBag::zero() to create an empty instanceMoney::convertedTo() now defaults to DefaultContext instead of $this's contextnull for the $context parameter:
CurrencyConverter::convert()Money::of()Money::ofMinor()Money::zero()Money::convertedTo()Money::allocate() signature has changed: replace allocate(1, 2, 3) with allocate([1, 2, 3], AllocationMode::FloorToFirst) to keep the same behaviour as beforeMoney::allocateWithRemainder() has been removed: replace allocateWithRemainder(1, 2, 3) with allocate([1, 2, 3], AllocationMode::BlockSeparate) to keep the same behaviour as beforeMoney::split() signature has changed: replace split(3) with split(3, SplitMode::ToFirst) to keep the same behaviour as beforeMoney::splitWithRemainder() has been removed: replace splitWithRemainder(3) with split(3, SplitMode::Separate) to keep the same behaviour as beforeMoney with AutoContext:
quotient()remainder()quotientAndRemainder()allocate()split()MoneyBag no longer retains zero-balance currencies after plus()/minus() operationsExchangeRateProvider::getExchangeRate() signature has changed: it now accepts Currency instances, and returns BigNumber|nullCurrencyConversionException has been renamed to ExchangeRateException, with ExchangeRateProviderException and ExchangeRateNotFoundException subclassesPdoProvider::setParameters() has been removed, use dimension bindings insteadPdoProvider constructor is now private, use PdoProvider::builder()->...->build() to create an instancePdoProviderConfiguration has been removed, use PdoProvider::builder() insteadCurrencyConverter::convert() signature has changed: parameter $dimensions now comes before $contextCachedProvider::invalidate() has been removed, pass a PSR-16 cache implementation to the constructor if you need to invalidate the cacheMoneyComparator constructor now requires a ComparisonMode instance, explicitly pass an instance of PairwiseMode to keep the same behaviour as beforeConfigurableProvider is now immutable: setExchangeRate() has been removed, use ConfigurableProvider::builder()->addExchangeRate()->build() insteadMoney::convertedTo()RationalMoney::convertedTo()CurrencyConverter::convert()CurrencyConverter::convertToRational()1:
Money::convertedTo()RationalMoney::convertedTo()@internalContext methods are now @internal: userland code should only rely on constructorsContext, Monetary, and MoneyException are now sealed: userland implementations are no longer supportedExchangeRateProvider implementations now consistently return 1 for same-currency pairsDeprecated methods removed:
AbstractMoney::to() has been removed, use toContext() insteadAbstractMoney::isAmountAndCurrencyEqualTo() has been removed, use isSameValueAs() insteadMoney::total() has been removed, use sum() insteadMoney::getUnscaledAmount() has been removed, use getAmount()->getUnscaledValue() insteadRationalMoney::simplified() has been removed, RationalMoney is always in its simplest form nowMoneyBag::add() has been removed, use plus() instead, which returns a new instanceMoneyBag::subtract() has been removed, use minus() instead, which returns a new instanceThe following breaking changes only affect you if you're using named arguments:
Currency::ofNumericCode() now uses $numericCode as the parameter nameIsoCurrencyProvider::getCurrencyByNumericCode() now uses $numericCode as the parameter nameMoneyBag::plus() and minus() now use $that as the parameter name⚠️ Deprecations
MoneyBag::fromMonies() is deprecated, use of() insteadProviderChain is deprecated, use ChainProvider instead✨ New features
ExchangeRateProvider, CurrencyConverter and MoneyComparatorMoney, RationalMoney, and MoneyBag in MoneyComparatorMoneyComparatorMoney::allocate() API with five algorithms, exposed through the new AllocationMode enum:
FloorToFirst (this is the implementation allocate() used previously)FloorToLargestRatioFloorToLargestRemainderFloorSeparateBlockSeparate (this is the implementation allocateWithRemainder() used previously)Money::split() API with two algorithms, exposed through the new SplitMode enum:
ToFirst (this is the implementation split() used previously)Separate (this is the implementation splitWithRemainder() used previously)MoneyMismatchException now has explicit CurrencyMismatchException and ContextMismatchException subclassesMoneyFormatException, thrown by MoneyFormatter::format()MoneyBag: isZero(), multipliedBy(), dividedBy(), negated(), isEqualTo(), of() (replaces fromMonies())RationalMoney: min(), max(), sum()CachedProviderChainProvider (replaces ProviderChain)PdoProviderMethod AbstractMoney::isAmountAndCurrencyEqualTo() is deprecated, use isSameValueAs() instead
⚠️ Deprecations
AbstractMoney::isAmountAndCurrencyEqualTo() is deprecated, use isSameValueAs() instead🔄 Reverted deprecations
AbstractMoney::isEqualTo() with a money in a different currency (introduced in 0.12.1) has been removed; this method will continue to throw a MoneyMismatchException✨ New features
AbstractMoney::isSameValueAs() (replaces isAmountAndCurrencyEqualTo())Money::allocate() & allocateWithRemainder() now accept BigNumber|int|string and support decimal & rational ratios
✨ New features
Money::allocate() & allocateWithRemainder() now accept BigNumber|int|string and support decimal & rational ratiosMoney::remainder()abs() and negated() are now available on AbstractMoney📌 Compatibility
brick/math version 0.17✨ New features
Money::allocate() & allocateWithRemainder() now accept BigNumber|int|string and support decimal & rational ratiosMoney::remainder()abs() and negated() are now available on AbstractMoney📌 Compatibility
brick/math version 0.17Compatibility with brick/math version 0.16
📌 Compatibility
brick/math version 0.16⚠️ Deprecations
AbstractMoney::isEqualTo() with a money in a different currency now triggers a deprecation notice; false instead of throwing a MoneyMismatchException. Use compareTo() === 0 if you need the throwing behaviour.0.12.3.📌 Compatibility
brick/math version 0.16Method RationalMoney::simplified() is deprecated, as it is now a no-op
💥 Breaking changes
(string) $float to get the same behaviour as before (brick/math#105):
Money::of(), ofMinor(), plus(), minus(), multipliedBy(), dividedBy(), quotient(), quotientAndRemainder(), convertedTo()RationalMoney::of(), plus(), minus(), multipliedBy(), dividedBy()AbstractMoney::compareTo(), isEqualTo(), isLessThan(), isLessThanOrEqualTo(), isGreaterThan(), isGreaterThanOrEqualTo()ConfigurableProvider::setExchangeRate()Currency::of() with a numeric code is no longer supported, use Currency::ofNumericCode() instead (#104)Currency instance from Currency::ofNumericCode() instead (#104):
Money::of()Money::ofMinor()Money::zero()Money::convertedTo()RationalMoney::of()CurrencyConverter::convert()CurrencyConverter::convertToRational()IsoCurrencyProvider::getCurrency()RationalMoney is now always simplified to lowest terms: USD 25/100 is automatically simplified to USD 1/4Currency::$numericCode is now nullablePdoProviderConfiguration now has a private constructor, use a factory method insteadMoney::create() is now protectedClass name case changes:
ISOCurrencyProvider has been renamed to IsoCurrencyProviderPDOProvider has been renamed to PdoProviderPDOProviderConfiguration has been renamed to PdoProviderConfigurationDeprecated methods removed:
Currency::is() has been removed, use Currency::isEqualTo() insteadMoneyBag::getAmount() has been removed, use MoneyBag::getMoney()->getAmount() insteadMoney::formatTo() has been removed, use Money::formatToLocale() insteadMoney::formatWith() has been removed, use MoneyNumberFormatter::format() instead⚠️ Deprecations
RationalMoney::simplified() is deprecated, as it is now a no-opMoney::getUnscaledAmount() is deprecated, use getAmount()->getUnscaledValue() insteadMoney::total() is deprecated, use sum() insteadAbstractMoney::to() is deprecated, use toContext() insteadnull to the $context parameter of the following methods is deprecated, use named arguments if you need to skip $context:
CurrencyConverter::convert()Money::of()Money::ofMinor()Money::zero()null to the $context parameter of Money::convertedTo() is deprecated, use an explicit Context instance; the default will change to DefaultContext in a future versionMoneyBag with new is deprecated, use MoneyBag::zero() or MoneyBag::fromMonies() insteadMoneyBag::add() is deprecated, use plus() instead, which returns a new instanceMoneyBag::subtract() is deprecated, use minus() instead, which returns a new instance📌 Compatibility
brick/math:~0.15👌 Improvements
InvalidArgumentException thrown now implement MoneyExceptionCashContext::applyTo() now performs step ⟷ scale validation✨ New features
AbstractMoney::toRational()Money::sum() (replaces total())RationalMoney::convertedTo()RationalMoney::abs()RationalMoney::negated()MoneyBag immutable API:
MoneyBag::zero()MoneyBag::fromMonies()MoneyBag::plus()MoneyBag::minus()ContextException thrown when a context cannot be appliedPDOProviderConfiguration factory methods:
forCurrencyPair()forFixedSourceCurrency()forFixedTargetCurrency()MoneyBag now implements JsonSerializableMoney::create() is now marked as @internal , and will be made protected in version 0.12
⚠️ Deprecations
Money::create() is now marked as @internal, and will be made protected in version 0.12Added explicit trigger_deprecation() calls to methods that were already marked as @deprecated , so deprecation notices are now emitted at runtime
⚠️ Deprecations
trigger_deprecation() calls to methods that were already marked as @deprecated, so deprecation notices are now emitted at runtime📌 Compatibility
brick/math:~0.14.4👌 Improvements
Calling Currency::of() with a numeric code is deprecated, use Currency::ofNumericCode() instead
💥 Breaking changes
final:
CurrencyConversionExceptionMoneyMismatchExceptionUnknownCurrencyExceptionCustomContext now validates the step and will throw an exception if an invalid step is givenMoneyContainer has been removed (replaced with Monetary)AbstractMoney::getAmounts() has been removed (replaced with getMonies())MoneyBag::getAmounts() has been removed (replaced with getMonies())CurrencyConverter::convert() and convertToRational() now accept a Monetary instance (which still includes Money, RationalMoney and MoneyBag)MoneyBag::add() and subtract() now accept a Monetary instance (which still includes Money, RationalMoney and MoneyBag)⚠️ Deprecations
Currency::of() with a numeric code is deprecated, use Currency::ofNumericCode() insteadISOCurrencyProvider::getCurrency() with a numeric code is deprecated, use getCurrencyByNumericCode() insteadCurrencyConverter::convert() or convertToRational() with a numeric currency code is deprecated, use a Currency instance insteadMoney::of(), ofMinor(), zero() or convertedTo() with a numeric currency code is deprecated, use a Currency instance insteadRationalMoney::of() with a numeric currency code is deprecated, use a Currency instance insteadMoneyBag::getAmount() is deprecated, use getMoney() insteadMoney::formatTo() is deprecated, use Money::formatToLocale() insteadMoney::formatWith() is deprecated, use MoneyNumberFormatter::format() insteadCurrency::is() is deprecated, use Currency::isEqualTo() insteadImportant
The convenience of passing a currency by ISO numeric code in addition to alphabetic code has been deprecated, leaving only alphabetic-code lookup in generic APIs. For example, Money::of() will accept Currency|string in the future, instead of Currency|string|int today.
This makes explicit the separation between retrieval by alphabetic code, which has strong backwards compatibility guarantees, and retrieval by numeric code, which may change in minor versions due to ISO reassignments.
This will require users to explicitly obtain a currency through Currency::ofNumericCode(), which is documented as not being covered by the same BC guarantees.
✨ New features
Money::of(), Currency::of(), etc. (#104 by @survik1)CurrencyTypeCurrency::getCurrencyType() returns the type of the currencyCurrency::ofNumericCode() returns a currency by its numeric ISO 4217 codeCurrency::isEqualTo() compares two currencies for equality (replaces is())ISOCurrencyProvider::getCurrencyByNumericCode() returns a currency by its numeric codeISOCurrencyProvider::getHistoricalCurrenciesForCountry() returns historical currencies for a countryMoneyBag::getMoney() returns the contained amount in a given currency (replaces getAmount())MoneyBag::getMonies() returns the contained monies (replaces getAmounts())Money::formatToLocale() formats the amount to a locale (replaces formatTo()) (#105 by @mklepaczewski)RationalMoney::zero() returns a zero RationalMoney in a given currencyMonetary (replaces MoneyContainer)MoneyFormatter formats a given Money object (#105 by @mklepaczewski)MoneyLocaleFormatter formats a given Money object to a locale (#105 by @mklepaczewski)MoneyNumberFormatter formats a given Money object using a NumberFormatter instance (#105 by @mklepaczewski)Compatibility with brick/math version 0.14 (#101 by @markwalet)
👌 Improvements
brick/math version 0.14 (#101 by @markwalet)Add possibility to pass previous exception in CurrencyConversionException (#99 by @arokettu)
✨ New features
CurrencyConversionException (#99 by @arokettu)Compatibility with brick/math version 0.13 (#96 by @ekvedaras)
👌 Improvements
brick/math version 0.13 (#96 by @ekvedaras)ZWG (Zimbabwe Gold) has been added
💥 ISO currency changes
ZWG (Zimbabwe Gold) has been addedZWL (Zimbabwean Dollar) has been removedSLL (Sierra Leonean Leone) has been removedZW) has been changed to ZWG (Zimbabwe Gold)SLL currency has been removed from Sierra Leone (SL), which only has SLE nowPDOProviderConfiguration no longer has getters, its properties are public readonly
💥 Breaking changes
PDOProviderConfiguration no longer has getters, its properties are public readonlyRoundingMode from brick/math is now an enum, so:
int rounding mode now accept a RoundingMode instance insteadRoundingMode::UPCurrency now implements JsonSerializable (#79).
Due to Croatia's adoption of the Euro on January 1st, 2023:
💥 Breaking changes
HRK currency (Kuna) has been removed from the ISO currency providerHR country (Croatia) is now mapped to EUR (Euro)PDOProviderConfiguration now has a proper constructor, and its properties are no longer publicPDOProviderConfiguration now throws exceptions in the constructor when configuration is invalidExchangeRateProvider implementation, you will need to update your getExchangeRate() method signatureStringable objects to of() or any of the methods internally calling of(), and have strict_types enabled, you will need to explicitly cast these objects to string firstCompatibility with brick/math version 0.11
👌 Improvements
brick/math version 0.11JSON extension is now required for PHP 7.4 (always available with PHP >= 8.0)
💥 Breaking changes
AbstractMoney is now officially sealed, extending it yourself is not supported✨ New features
Money and RationalMoney now implement JsonSerializableAbstractMoney::getAmount() now has a return type
💥 Breaking changes
AbstractMoney::getAmount() now has a return typeCurrencyConverter's constructor does not accept a default $context anymoreCurrencyConverter::convert() now requires the $context previously accepted by the constructor as third parameterMoney::allocateWithRemainder() now refuses to allocate a portion of the amount that cannot be spread over all ratios, and instead adds that amount to the remainder (#55)Money::splitWithRemainder() now behaves like allocateWithRemainder()✨ New ISO currencies
SLE (Leone) in Sierra Leone (SL)👌 Improvements
brick/math version 0.10Nothing published for this version
These methods perform like their allocate() and split() counterparts, but append the remainder at the end of the returned array instead of spreading i
✨ New methods
Money::allocateWithRemainder()Money::splitWithRemainder()These methods perform like their allocate() and split() counterparts, but append the remainder at the end of the returned array instead of spreading it over the first monies.
Thanks @NCatalani!
BaseCurrencyProvider now always returns a BigNumber for convenience (#37). This is useful if you're using BaseCurrencyProvider on its own, not just in
👌 Improvement
BaseCurrencyProvider now always returns a BigNumber for convenience (#37).
This is useful if you're using BaseCurrencyProvider on its own, not just in CurrencyConverter.
Thanks @rdarcy1!
compatibility with brick/math version 0.9
👌 Improvements
brick/math version 0.9⚠️ Caution
When using brick/math version 0.9, the Money factory methods such as of() and ofMinor() now accept decimal numbers in the form .123 and 123., and do not throw an exception anymore in this case.
MoneyBag::getAmount(), add() and subtract() would throw an exception when using a custom currency (#25).
🐛 Bug fix
MoneyBag::getAmount(), add() and subtract() would throw an exception when using a custom currency (#25).
AbstractMoney::isAmountAndCurrencyEqualTo() compares a money to another.
✨ New method
AbstractMoney::isAmountAndCurrencyEqualTo() compares a money to another. (#17)
This method is different from isEqualTo() in 2 aspects:
false if the money is in another currency, instead of throwing an exception.MoneyBag::getAmount() now accepts an ISO numeric currency code as well
🛠 Improvements
MoneyBag::getAmount() now accepts an ISO numeric currency code as well✨ New methods
CurrencyConverter::convertToRational() converts to a RationalMoney (#22)Performance improvement when calling Money::formatTo() many times for the same locale.
Performance improvement when calling Money::formatTo() many times for the same locale.
Added support for brick/math version 0.8.
Added support for brick/math version 0.8.
Deprecated method BigRational::toMoney() has been removed, use BigRational::to() instead;
Breaking Changes
BigRational::toMoney() has been removed, use BigRational::to() instead;BigRational::__toString() now always outputs the amount in non-simplified rational form.New methods
BigRational::simplified() returns a copy of the money with the amount simplified.ISO currency list update.
ISO currency list update.
ISO currency list update.
ISO currency list update.
Money::formatTo() can now format the amount as a whole number:
Money::formatTo() can now format the amount as a whole number:
formatTo(string $locale, bool $allowWholeNumber = false) : string
By default, formatTo() always outputs all the fraction digits:
Money::of('23.5', 'USD')->formatTo('en_US'); // $23.50
Money::of(23, 'USD')->formatTo('en_US'); // $23.00
But can now be allowed to return the whole number by passing true as a second argument:
Money::of('23.5', 'USD')->formatTo('en_US', true); // $23.50
Money::of(23, 'USD')->formatTo('en_US', true); // $23
Note that this version now requires brick/math version 0.7.3. This is not a BC break. If you've locked your composer.json to an earlier version, you will just not be able to install brick/money version 0.3.2.
ISO currency list update.
ISO currency list update.
Although this is technically a breaking change and requires a version bump, your code is unlikely to be affected, unless you're creating CurrencyConve…
New methods:
CurrencyConversionException::getSourceCurrencyCode()CurrencyConversionException::getTargetCurrencyCode()This allows to programmatically get the failing currency pair when an exchange rate is not available.
Breaking change:
CurrencyConversionException constructor signature changedAlthough this is technically a breaking change and requires a version bump, your code is unlikely to be affected, unless you're creating CurrencyConversionException instances manually (you shouldn't).
ISO currency list update.
ISO currency list update.
Bug fix: Money::allocate() incorrectly allocated negative monies.
Bug fix: Money::allocate() incorrectly allocated negative monies.
Money::formatTo() now always respects the scale of the Money.
Money::formatTo() now always respects the scale of the Money.
New method: CustomContext::getScale()
New method: CustomContext::getScale()
BigRational::toMoney() has been deprecated; use to() instead. This is the result of a factorization of a common feature in Money and RationalMoney.
BigRational::toMoney() has been deprecated; use to() instead. This is the result of a factorization of a common feature in Money and RationalMoney.Money::formatTo() now always respects the scale of the Money
Backports from 0.2.x:
CustomContext::getScale()Money::formatTo() now always respects the scale of the MoneyMoney::allocate() incorrectly allocated negative moniesFirst beta release!
First beta release!
Your coding agent can read these notes before it upgrades. Set up the MCP server →