evp / money
货币库
2.8.0
2023-04-20 09:07 UTC
Requires
- php: ^7.0 || ^8.0
- ext-bcmath: *
- ext-mbstring: *
- maba/math: ^1.0
- maba/monetary: ^0.10.0
- paysera/lib-dependency-injection: ^1.0
- paysera/lib-serializer: ^1.0 || ^2.0 || ^3.0
- symfony/dependency-injection: ^2.3 || ^3.0 || ^4.0 || ^5.0
Requires (Dev)
- phpunit/phpunit: ^6.5 || ^9.6
- yoast/phpunit-polyfills: ^1.0
Suggests
- paysera/lib-serializer: Allows to Serialize/Deserialize Money objects
README
与其将价格、利润或其他金额存储在浮点数或整数变量中,不如使用货币值对象。因为它将金额与货币组合,而金额没有货币则信息不足。
安装
composer require evp/money
为什么不是浮点数?
- 浮点数在处理金钱操作时不可靠,因为它们可能会丢失精度,而且分可以丢失。
为什么不是整数?
- 当最大整数值达到时,可能会发生疯狂的事情:它可能会被截断,甚至变成负数。这些类型的错误可能是关键的,特别是在处理金钱时。在32位系统(以及任何Windows系统)上,最大整数值为2147483647。由于这足以满足大多数情况,因此一些货币与其他货币相比相对非常小(例如,2,147,483,647.00 BYR 大约相当于 150,000.00 EUR)。
- 可能存在一些情况,在这种情况下,金钱应该在不四舍五入到最小可用单位的情况下进行计算或保存。例如,非常小的佣金(分的部分),当大量此类佣金相加时,可能会增加大量金额。
- 当将金额存储为整数时,在输出结果或进行任何其他操作之前,您必须始终考虑到货币除数(该货币中最小可用单位)。例如,大多数货币的最小单位是分,而巴林第纳尔的最小单位是0.001,而日元没有分。或者,如果您总是以分的形式存储单位,您就无法表示某些货币的最小单位。
架构
Money
是值对象 - 它是不可变的。换句话说,如果您需要更改金额或货币,只需创建另一个Money
对象。相同的Money
对象可以在多个地方引用,因此仅更改此对象的字段可能会无意中更改其他地方的资金金额或货币。
API
Money
类提供了与另一个Money
实例进行算术和比较操作的独立逻辑。所有算术操作都返回一个新的Money
实例。
Money::add
- 将当前金钱金额添加到给定金额;如果货币不同,则抛出异常。Money::sub
- 从当前金钱金额中减去给定金钱金额;如果货币不同,则抛出异常。Money::mul
- 将当前金钱金额乘以给定乘数。Money::div
- 将当前金钱金额除以给定除数。Money::negate
- 取当前金钱金额的相反数。Money::round
- 将当前金钱金额四舍五入到给定的小数位数;如果没有给出精度,则四舍五入到当前货币的最大精度。Money::ceil
- 将当前金钱金额四舍五入到上限;如果没有给出精度,则四舍五入到当前货币的最大精度。Money::floor
- 将当前金钱金额四舍五入到底限;如果没有给出精度,则四舍五入到当前货币的最大精度。Money::check
- 检查当前金额是否不是太小;如果是,则抛出异常。Money::isGt
- 如果当前金钱大于给定金额,则返回。Money::isGte
- 如果当前金钱大于或等于给定金额,则返回。Money::isLt
- 如果当前金钱小于给定金额,则返回。Money::isLte
- 如果当前金钱小于或等于给定金额,则返回。Money::isEqual
- 如果当前金钱等于给定金额,则返回。Money::isNegative
- 如果当前金钱是负数,则返回。Money::isPositive
- 如果当前金钱是正数,则返回。Money::isZero
- 如果当前金钱金额为零,则返回。Money::isSameCurrency
- 判断当前货币是否与给定的货币相同。Money::abs
- 返回绝对金额的货币。Money::getArrayRepresentation
- 返回包含键amount
和currency
的数组。Money::getAsString
- 返回将amount
和currency
通过空格连接的字符串。Money::getFraction
- 返回给定货币支持的十进制位数。
用法
$money = new Money(1, 'EUR'); $timesTwo = $money->mul(2); $money->isLt($timesTwo); // true