Skip to content
CAI
Software that uses CAICheck a score

moneyphp/money

69.4

Adequate · 19 September 2026

8.3k

lines of production code

PHP

primary language

1

measurement over time

CAI band scale
CAI lens gauges

What this system is

This system is a PHP library for handling monetary values and currency conversions, designed with a focus on precision and type safety. It provides core value objects for money and currency, supported by pluggable calculators using BCMath or GMP for accurate decimal arithmetic. The library also includes comprehensive tools for parsing and formatting monetary strings, managing currency data from ISO standards and cryptocurrencies, and fetching exchange rates from various providers.

How it got here

2011–2014 — Project modernization and restructure

6 changes.

The project underwent a comprehensive restructure, migrating from the legacy Verraes\\Money namespace to the modern Money\\Money identity with PHP 8+ support. This period involved rebuilding the build infrastructure with Composer and PHPStan, upgrading the test suite to PHPUnit 10, and migrating documentation to Sphinx. The codebase was refactored to introduce new abstractions for calculations and currency conversion while removing deprecated legacy files.

2015–2016 — cryptocurrency support and precision improvements

11 changes.

The project expanded its capabilities to support cryptocurrencies by adding new currency repositories, parsers, and formatters for Bitcoin and other digital assets. Significant enhancements were made to the calculator module with precise decimal handling via BCMath and GMP, alongside a comprehensive overhaul of exception types and exchange rate providers for better error handling and flexibility.

2017–2021 — Testing, immutability, and benchmarking

4 changes.

This period focused on enhancing code quality and performance verification through the addition of PHPUnit comparators for Money objects and static analysis rules enforcing immutability. The team also introduced system locale configuration scripts and comprehensive benchmarks to measure the performance of Money, Number, and Calculator operations.

Features

Added PHPUnit Comparator for Money objects

A new \Comparator\ class has been added to the \src/PHPUnit\ directory to enable precise comparison of \Money\ objects in PHPUnit tests. This component allows developers to register the comparator in their test bootstrap, ensuring that assertions on monetary values produce clear, formatted failure messages rather than generic object comparison errors.

src/PHPUnit · high confidence

Added cryptocurrency support and factory generation scripts

The resources directory now includes \binance.php\ and \currency.php\ data files, expanding the library's currency coverage to include cryptocurrencies (such as AAVE, ADA, ARB) alongside traditional ISO currencies. Additionally, \generate-money-factory.php\ and \generate-teller-factory.php\ scripts have been added to automatically generate PHP factory traits (\MoneyFactory\ and \TellerFactory\) based on the available currency data, enabling convenient static factory methods for creating Money and Teller instances.

resources · high confidence

Added script to configure system locales

A new shell script, hack/setup-locales.sh, has been added to the repository. This script configures the system's locale generation by appending entries for English (US and CA), Spanish (ES), and Russian (RU) in both ISO-8859 and UTF-8 encodings to /etc/locale.gen, and then executes locale-gen and update-locale to apply these settings.

hack · high confidence

New and improved money parsers for Bitcoin, decimal, and international formats

The parser module introduces several new parsing capabilities and refines existing ones. A new AggregateMoneyParser allows chaining multiple parsers to attempt parsing a string against different formats until one succeeds. Support for Bitcoin is added via a dedicated BitcoinMoneyParser that handles the BTC symbol and fractional digits. Standard decimal strings are now parsed by a new DecimalMoneyParser, which requires a fallback currency and handles leading zeros and empty strings. Additionally, the library adds IntlLocalizedDecimalParser for parsing locale-specific decimal strings using the PHP intl extension, complementing the existing IntlMoneyParser which extracts currency from the string. These changes expand the range of input formats the library can handle out of the box.

src/Parser · high confidence

New currency repository implementations and aggregation

The src/Currencies directory now includes several new classes to manage currency data: AggregateCurrencies combines multiple currency sources; BitcoinCurrencies handles Bitcoin (XBT) with 8 decimal places; CachedCurrencies provides PSR-6 caching for currency lookups; CryptoCurrencies loads supported crypto codes from Binance resources; CurrencyList allows custom currency definitions; and ISOCurrencies now exposes a numericCodeFor method to retrieve ISO 4217 numeric codes in addition to existing functionality.

src/Currencies · high confidence

New exchange implementations for third-party providers, fixed rates, and indirect conversions

The src/Exchange directory now includes several new classes to handle currency exchange rates: ExchangerExchange and SwapExchange integrate with third-party providers (Exchanger and Swap libraries) to fetch live rates, FixedExchange allows using a static array of rates, ReversedCurrenciesExchange attempts to derive a rate by querying the reverse currency pair if the direct one is unavailable, and IndirectExchange calculates rates through a chain of intermediate currency conversions when a direct pair is not found.

src/Exchange · high confidence

New formatters for Bitcoin, decimal, and intl-based currency formatting

The Formatter component now includes several new classes to handle specific formatting needs: BitcoinMoneyFormatter formats Bitcoin currency with configurable fraction digits; DecimalMoneyFormatter outputs a plain decimal string representation of money; IntlMoneyFormatter and IntlLocalizedDecimalFormatter leverage the PHP intl extension for locale-aware currency and decimal formatting; and AggregateMoneyFormatter allows routing formatting to different formatters based on currency code, with a fallback for unmatched currencies.

src/Formatter · high confidence

Removals

Removal of legacy Verraes\\Money library files

The \lib/MathiasVerraes/FowlerMoney\ directory has been removed, deleting the legacy \Verraes\\Money\ namespace files including the \Currency\ interface, \Euro\ and \Usd\ currency implementations, the \Money\ value object, and the \InvalidArgumentException\. This eliminates the deprecated money handling classes from the codebase.

lib/MathiasVerraes · high confidence

Architecture

Library restructured to src/ with new currency conversion and calculator abstractions

The library has been reorganized from the legacy lib/MathiasVerraes/FowlerMoney namespace into the modern Money namespace under src/. This change introduces a Calculator interface to abstract arithmetic operations, a Converter class to handle currency conversions using an Exchange interface, and new interfaces for Currencies and MoneyParser. The Money value object now stores amounts as strings and delegates calculations to the calculator, while the Currency class provides a zero() factory method and the CurrencyPair class supports ISO string parsing. Additionally, a Teller utility class is added to simplify common monetary comparisons and arithmetic across different currencies.

src · high confidence

Behavioural changes

Introduce specific exception subtypes for clearer error handling

The library now provides distinct exception classes for common error scenarios, replacing generic exceptions with more specific types. Users catching errors will now encounter \CurrencyMismatchException\ when comparing incompatible currencies, \DivisionByZeroException\ and \ModuloByZeroException\ for arithmetic errors, \FormatterException\ when string conversion fails, \ParserException\ for invalid input strings, \UnknownCurrencyException\ for missing currency definitions, and \UnresolvableCurrencyPairException\ when exchange rates are unavailable. These new classes implement a common \Exception\ interface and extend standard PHP exceptions, allowing for more precise error handling in application code.

src/Exception · high confidence

Migrate documentation to Sphinx with reStructuredText and new theme

The documentation has been rebuilt using Sphinx and reStructuredText (.rst), replacing the previous format. This change introduces a new visual theme (sphinx\_rtd\_theme) with custom CSS for syntax highlighting and navigation, adds a favicon, and includes a spelling check target. The content now covers getting started, core concepts like immutability and type safety, and detailed feature pages for operations, comparisons, allocation, parsing, formatting, aggregation, and the Teller class.

doc · high confidence

New BcMath and GMP calculator implementations with precise decimal handling

The calculator module now includes dedicated implementations for the BCMath and GMP extensions, replacing or supplementing previous logic. The BcMathCalculator uses a fixed scale of 14 for decimal operations and implements specific rounding modes (half-up, half-down, half-even, half-odd, half-positive/negative infinity) via the Number class. The GmpCalculator, designed for systems without BCMath, handles decimal arithmetic by manually managing integer/fractional parts and uses GMP\_ROUND\_MINUSINF for division remainders. Both calculators enforce division-by-zero checks and support absolute value, ceiling, and floor operations, ensuring consistent behavior for negative numbers and decimal precision across the Money library.

src/Calculator · high confidence

Project restructure and modernization of build tooling

The project has been restructured from the legacy 'Verraes\\Money' namespace to 'Money\\Money' (moneyphp/money), updating the README, license, and documentation to reflect the new identity and PHP 8+ requirements. Build infrastructure has been modernized by removing the obsolete Ant build.xml in favor of Composer scripts, configuring PHPStan at level 6, and updating PHPUnit configuration to use the modern source/include syntax. Additionally, new configuration files (.editorconfig, .gitattributes, .readthedocs.yml) have been added to standardize code formatting, control distribution artifacts, and support Sphinx-based documentation hosting.

(repo-wide) · high confidence

Static analysis rule enforcing Money immutability

A new static analysis configuration file has been added to enforce that the Money class is treated as pure and immutable. This change ensures that downstream consumers and static analysis tools correctly identify Money objects as side-effect-free, preventing accidental mutation and improving type safety in static analysis checks.

static-analysis · high confidence

Test coverage

Added benchmarks for Money, Number, and Calculator operations; Added unit tests for BcMath and GMP calculators; Added unit tests for Exchange implementations; Added unit tests for currency collection classes; Added unit tests for parser components; Migrated test suite to PHPUnit 10 and modernized test infrastructure.

Dependencies

Initial dependency and build configuration setup

Established the project's dependency manifest (composer.json) and documentation requirements (doc/requirements.txt). The package now requires PHP 8.1–8.5 with bcmath and filter extensions, and includes development tools such as PHPUnit 10.5.9, PHPStan 2.2.5, and Doctrine Coding Standard 12.0. Documentation builds rely on Sphinx 7.2.6 and related themes. This entry reflects the initial configuration of these build and dependency files.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Baseline

  • First survey — no prior run to compare against. CAI 69.

Lenses

  • Code Health 98
  • Architecture 100
  • Maturity 56
  • Readiness 68
  • Security 90

Changes since last survey

  • 300 commits — 257 feature/other, 43 fixes

By area

  • (root) — 114 commits
  • (repo) — 39 commits
  • .github/workflows — 23 commits
  • src/Money.php — 17 commits
  • src/Teller.php — 13 commits
  • doc/features — 9 commits
  • src/Calculator — 9 commits
  • tests/Calculator — 9 commits
  • src/Parser — 7 commits
  • tests/Parser — 7 commits
  • src/Currencies — 5 commits
  • src/Exchange — 5 commits
  • src/Currency.php — 4 commits
  • src/Number.php — 4 commits
  • doc/conf.py — 3 commits
  • src/Formatter — 3 commits
  • tests/Formatter — 3 commits
  • benchmark/NumberInstantiationBench.php — 2 commits
  • doc/concept.rst — 2 commits
  • resources/binance.php — 2 commits

Notable commits

  • fix: Add jsonSerialize return types: - fixes PHP 8.1 deprecations - shows array shapes where applicable
  • fix: Applied automated CS fixes, improved github actions setup to run psalm/phpunit/phpcs from locally installed version
  • fix: Fix CS
  • fix: Fix GH actions (#609)
  • fix: Fix PHP 8.5 setlocale
  • fix: Fix build
  • fix: Fix comparison links of latest release & unreleased section
  • fix: Fix comparison links of v4.0.4 and Unreleased
  • fix: Fix psalm errors (#723)
  • fix: Fix type in currencies documentation
  • fix: Hunted down a few easy-fix mutants that were just about migrating phpspec scenarios to PHPUnit tests
  • fix: Merge pull request #686 from moneyphp/fixed-exchange-numeric-string
  • fix: Revert "include all extensions in composer.json, even when they are bundled with php (found after running maglnet/ComposerRequireChecker)"
  • fix: Revert removal of Money::fromFloat()
  • fix: Try reproduce bug #740 (#741)
  • fix: Updated currencies: added SLE and VED, removed HRK. Fixes #737. (#739)
  • fix: also revert the msi
  • fix: bugfix
  • fix: downgrade psalm due to bug (https://github.com/vimeo/psalm/pull/5989)
  • fix: fix GitHub workflow badge URL
  • …and 280 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

moneyphp/money was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 19 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit a5199443bfd20c3d3644b8445b09054a4c014191 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-13a154b7f5d1.