ecommerce-utilities / money
Installs: 24
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/ecommerce-utilities/money
Requires
- php: >= 8.1
- ext-bcmath: *
Requires (Dev)
- jetbrains/phpstorm-attributes: ^1.2
- phpstan/phpstan: >= 0.1
- phpunit/phpunit: ^10.0
- rector/rector: >= 0.1
README
A small, precise money helper class for arithmetic operations and comparisons with configurable decimal precision. Uses bcmath for deterministic decimal calculations.
- Namespace:
Ecommerce
- PHP: 8.1+
- Requires: PHP extension
ext-bcmath
Installation
composer require ecommerce-utilities/money
- Ensure the bcmath PHP extension is enabled (e.g.,
sudo apt-get install php-bcmath
and restart your web server/CLI). - Include the class in your project (e.g., via PSR-4 autoloading) and use the
Ecommerce
namespace.
Quickstart
<?php use Ecommerce\Money; // Create $price = Money::fromValue(19.99); // Default: 2 decimal places $tax = Money::fromValue(1.90, 2); // explicit precision $zero = Money::zero(); // 0.00 // Arithmetic $total = Money::add($price, $tax); // 21.89 $rest = Money::sub($total, 5); // 16.89 $multi = Money::mul($rest, 3); // 50.67 $share = Money::div($multi, 4); // 12.67 (with 2 decimals) // Comparisons $isSame = Money::isEqual(10, '10.00'); // true $isLeftGt = Money::isLeftSideGreater(5, 7); // true (5 < 7) $isRightGt = Money::isRightSideGreater(9.99, 9.98); // true (9.99 > 9.98) // Access and string representation $asFloat = $total->getValue(); // float 21.89 $dp = $total->getDecimalPrecision(); // int 2 echo (string) $total; // "21.89"
Controlling precision
- The default precision is 2 decimal places.
- You can set precision explicitly in several places:
- When creating:
Money::fromValue(123.456, 3)
- In operations:
Money::add($a, $b, 3)
- When creating:
- During operations, precision is determined as follows:
- The provided
$decimalPrecision
parameter (if set), - otherwise, the precision of a
Money
operand (if present), - otherwise, 2.
- The provided
Examples:
<?php use Ecommerce\Money; $a = Money::fromValue(1.2345, 4); $b = 2; $sumDefault = Money::add($a, $b); // uses 4 from the Money operand -> "3.2345" $sumForced = Money::add($a, $b, 3); // overrides -> "3.235"
Null, string, and float inputs
All methods accept Money
, int
, float
, numeric-string
, or null
(depending on the method):
<?php use Ecommerce\Money; Money::add(null, 10); // 10.00 Money::add(null, null); // 0.00 (Money::zero()) Money::sub(null, 5); // 0.00 Money::mul(10, null); // 0.00 Money::div(10, 0); // 10.00 (division by 0 returns the left operand)
Notes:
fromMoney($value)
returns the numeric value (float) regardless of the input type.- The string representation is always formatted according to the set precision, e.g.,
"12.30"
.
Best practices
- Define a consistent precision for a domain (e.g., currency: 2, crypto assets: 8).
- For critical calculations, pass the precision explicitly to
add/sub/mul/div
. - Use the comparison helpers instead of direct float comparisons.
API overview
- Creation:
Money::fromValue(null|Money|int|float|string $value, ?int $decimalPrecision = null): Money
Money::zero(): Money
- Arithmetic:
Money::add($a, $b, ?int $decimalPrecision = null): Money
Money::sub($a, $b, ?int $decimalPrecision = null): Money
Money::mul($a, $b, ?int $decimalPrecision = null): Money
Money::div($a, $b, ?int $decimalPrecision = null): Money
- Comparisons:
Money::isEqual($a, $b, ?int $decimalPrecision = null): bool
Money::isLeftSideGreater($a, $b, ?int $decimalPrecision = null): bool
// true when a < bMoney::isRightSideGreater($a, $b, ?int $decimalPrecision = null): bool
// true when a > b
- Access:
$money->getValue(): float
$money->getDecimalPrecision(): int
(string) $money
for formatted output
License
Feel free to use this class in your projects. Contributions and improvements are welcome.