browner12 / money
Requires
- php: >=5.5.0
- ext-intl: *
Requires (Dev)
- league/commonmark: 0.*
- mockery/mockery: 0.*
- phpunit/phpunit: 4.*
README
此包已被 ABANDONED。我们终于有一个好的社区货币包了,所以请查看 money/money。
此存储库于 2017 年 5 月 23 日被标记为 ABANDONED。它将一直可用到 2018 年 5 月 23 日。请在那时之前将此代码从您的项目中重构。
谢谢!
money
这是一个针对 PHP 的货币包。它包括一个 Money
、一个 Currency
和一个 Accountant
。理解这三个类之间的区别很重要。这些类之间的关系使得这个包与一些现有的 PHP 货币包不同。Money
由两个属性组成:一个数值和一个 Currency
。Currency
是一个描述符。它对值一无所知,但为 Money
提供描述值所需的信息。Accountant
处理您的 Money
。他可以对您的 Money
执行许多计算,包括添加、减去、求和、分配、计算税率等。
理解 Money
持有的值非常重要。Currency
有基本单位和子单位。对于美元,基本单位是美元。子单位是分。在内部,Money
以子单位跟踪其值。虽然您可以通过传递基本单位或子单位来创建一个 Money
对象,但我们默认假设您传递的是子单位。有关如何更改此假设的文档,请参阅下面的文档。
注意:Accountant
只能对同一 Currency
的多个 Money
执行操作。不同的 Currency
将抛出异常。如果您想将一个 Currency
转换为另一个,请使用 Accountant
的 exchange()
方法。您必须提供汇率。
谁应该使用此包
如果您正在运行电子商务网站并自行处理购物车和支付,请使用此包。此包提供了许多辅助函数,使计算行总计、税费、小计和总计变得非常简单。
谁不应该使用此包
如果您需要比货币的子单位更高的精度,请不要使用此包。例如,在金融界,美元通常跟踪到千分之一(4 位小数)。这相当于 1/100 分(子单位)。此包处理的最小值是货币的 1 个子单位,任何比 1 个子单位更精确的值都将四舍五入。
小心
请注意您的系统是 32 位或 64 位架构,因为这决定了您可以表示的最大整数值。对于 32 位,这是 2147483647,对于 64 位,这是 9223372036854775807。无论如何,对于大多数基数 100 的货币,这通常不会成为问题,除非您正在处理大量资金(数百万),但这是一件需要注意的事情。
PSRs
此包遵循 PSR-1 和 PSR-4。所有贡献都应遵循这些。
影响
本包受到了 sebastianbergmann/money 和 mathiasverraes/money 的影响。我确实喜欢这些包的某些部分,但也有一些我不喜欢的部分,所以我决定自己制作。具体来说,我认为这个包有更好的类布局和组织,类的之间的关系更准确地反映了现实世界。我还认为这个包通过 Accountant
类更好地遵循了 SRP(单一责任原则)。在其他包中,Money
类承担了太多的责任,包括执行计算。在这个包中,Money
只负责知道它的值和 Currency
,而 Accountant
负责执行计算。
安装
通过 Composer
$ composer require browner12/money
文档
有 3 个类可以操作:Currency
、Money
和 Accountant
。我们将逐一介绍。
对于所有文档,以下假设成立
- 使用
use
导入了所有合适的类 - 如果没有指定货币,则默认为美元 (USD)
货币对象
虽然它是可用的,但你永远不需要手动创建一个 Currency
对象。当你创建一个 Money
对象时,我们会为你处理它。但是,如果你确实需要,有一些简单的 '获取器' 可以访问其属性。
//create a US Dollar currency $currency = new USD(); //retrieve its properties echo $currency->currency(); // 'USD' echo $currency->name(); // 'US Dollar' echo $currency->code(); // 840 echo $currency->subunit(); // 100 echo $currency->precision(); // 2 //__toString magic method echo $currency; // 'USD (US Dollar)'
货币对象
如上所述,Money
对象由一个值和一个 Currency
组成。为了尽可能使用整数(而不是浮点数),内部值以子单位存储。默认情况下,值作为子单位数量传递,尽管这可以被覆盖(见下文)。
//create money $money = new Money(1000, 'usd', false);
第一个参数是值,是必需的。理想情况下它是一个整数,但很多时候那并不容易/可能(从一个数据库值中获取,该值将所有内容都作为字符串提供)。你可以传递一个整数、浮点数、看起来像整数的字符串,以及看起来像浮点数的字符串。内部包将确定传递了哪种类型,并相应地设置值。以下所有 4 个示例都将 Money
设置为 $10.00。
//pass an integer $integer = new Money(1000); //pass a float $float = new Money(1000.00); //pass a string integer $stringInteger = new Money('1000'); //pass a string float $stringFloat = new Money('1000.00');
第二个参数是货币,是可选的。默认值是 'USD'。你不能传递一个货币对象,而是传递 3 个字母的货币字符串。例如,'USD' 代表美元,'EUR' 代表欧元,'AUD' 代表澳大利亚元。字符串不区分大小写。
//us dollar $usd = new Money(1000, 'usd'); //euro $eur = new Money(1000, 'EUR'); //australian dollar $aud = new Money(1000, 'aUd');
第三个参数是一个布尔值,是可选的。默认值是 FALSE。在传递值时,我们将假设你给出的是子单位数量。如果你想要给出基本单位数量,将第三个参数传递为 TRUE。内部,值将转换为子单位,以保持对整数的使用。
//create money worth 10 USD $money = new Money(1000, 'usd'); //create money worth 1000 USD $money = new Money(1000, 'usd', true);
Money
对象提供了以下公共方法
$money = new Money(1234, 'usd'); //get the subunits echo $money->subunits(); // 1234 //get the value (base units) echo $money->value(); // 12.34 //get currency echo $money->getCurrency(); // currency object //format using built-in PHP number formatter (PHP INTL package required) echo $money->format(); // $12.34 //can pass a locale as parameter, default is 'en-US' echo $money->format('en-CA'); // US$12.34 echo $money->format('de_DE'); // 12,34 $ //magic json serialize echo json_serialize($money); // ['value' => 12.34, 'subunits' => 1234, 'currency' => currency object, ] //magic toString echo $money; // $12.34
会计对象
会计对象负责处理您的Money
。对于大多数方法,它将返回一个新的Money
对象。它接受一个可选的构造函数参数,即舍入模式。默认值是PHP_ROUND_HALF_UP
。请注意,这不是一个字符串,而是一个PHP常量。会计对象有许多基本方法,如加法、减法和乘法,还有一些辅助方法,如计算税费或计算购物车的总价。以下我们将逐一介绍每个公共方法。当一个方法返回一个Money
对象时,我们将显示结果的小数部分值。
$accountant = new Accountant();
加法
接受两个参数,都是Money
对象,并将它们相加。它返回一个Money
对象。
@param Money @param Money @return Money $money1 = new Money(1234); $money2 = new Money(2532); echo $accountant->add($money1, $money2); // 3766
减法
接受两个参数,都是Money
对象,并从第一个中减去第二个。它返回一个Money
对象。
@param Money @param Money @return Money $money1 = new Money(2532); $money2 = new Money(1234); echo $accountant->add($money1, $money2); // 1298
求和
接受一个数组参数,并计算所有值的总和。请注意,数组中不是Money
对象的所有元素都将被过滤掉,并且不会抛出错误。
@param array @return Money $money1 = new Money(1234); $money2 = new Money(2532); $money3 = new Money(745); $money4 = new Money(33); echo $accountant->sum([$money1, $money2, $money3, $money4]); // 4544
乘法
将Money
对象乘以一个浮点值,并返回一个Money
对象。请注意这里可能发生的舍入。
@param Money @param float @return Money $money = new Money(1234); echo $accountant->multiply($money, 1.23); // 1518
取反
返回一个带有原始值的负值的新的Money
对象。
@param Money @return Money $money = new Money(1234); echo $accountant->negate($money); // -1234
折扣
折扣是一个包装函数,它将对Money
应用百分比折扣,并返回一个具有新值的对象。以下示例将对售价为21.99美元的商品应用12.5%的折扣。
@param Money @param float @return Money $money = new Money(2199); echo $accountant->discount($money, 12.5); // 1924
税费
税费是一个包装函数,允许您传递一个百分比值(而不是小数)来计算税费。以下示例计算当税费率为5.5%时,12.50美元的税费。
@param Money @param float @return Money $money = new Money(1250); echo $accountant->tax($money, 5.5); // 69
小计
小计是处理购物车时的便捷方法。它将接受一个实现了包含OrderLineInterface
的对象数组,并计算小计。这是每种产品的数量乘以单价的总和。OrderLineInterface
仅强制执行getQuantity
和getUnitPrice
契约。以下示例中,我们假设OrderLine
对象实现了OrderLineInterface
,并且它是通过传递单价然后是数量来构造的。
@param array @return Money $lines = [ new OrderLine(new Money(1000), 2), new OrderLine(new Money(1299), 1), new OrderLine(new Money(350), 3), ]; echo $accountant->subtotal($lines); // 4349
从数组获取小计
此方法与'小计'相同,但它不需要OrderLineInterface
。相反,您可以传递一个数组。
$lines = [ ['quantity' => 2, 'unitPrice' => new Money(1000)], ['quantity' => 1, 'unitPrice' => new Money(1299)], ['quantity' => 3, 'unitPrice' => new Money(350)], ]; echo $accountant->subtotalFromArray($lines); // 4349
总计
此方法计算购物车总额。传递订单行、税率、运费(可选)和处理费(可选)。
@param array @param float @param Money @param Money @return Money //order lines $line1 = new OrderLine(new Money(1499), 1); $line2 = new OrderLine(new Money(299), 3); $line3 = new OrderLine(new Money(525), 2); //tax rate $taxRate = 5.5; //shipping and handling $shipping = new Money(375); $handling = new Money(100); //calculate total echo $accountant->total([$line1, $line2, $line3], $taxRate, $shipping, $handling); // 4111
分配
分配允许我们将Money
分成'n'个部分。它不会简单地分割,因为很多时候会有余数,所以每个部分不一定会得到相同的金额。
@param Money @param int @return array $money = new Money(1250); echo $accountant->allocate($money, 4); // [313, 313, 312, 312]
兑换
此方法允许您将一种货币兑换为另一种货币。您必须提供汇率。以下示例中,1美元等于0.87欧元。
@param Money @param string @param float @return Money $usd = new Money(1000); echo $accountant->exchange($usd, 'eur', 0.87); // 870
比较
此方法允许您查看一个Money
是否大于、小于或等于另一个Money
。它返回-1表示小于,1表示大于,0表示等于。
@param Money @param Money @return int $money1 = new Money(1000); $money2 = new Money(1000); $money3 = new Money(1001); echo $accountant->compare($money1, $money2); // 0 echo $accountant->compare($money1, $money3); // -1 echo $accountant->compare($money3, $money1); // 1
大于
这是compare函数的包装函数。如果第一个Money
大于第二个Money
,则返回TRUE
。
@param Money @param Money @return bool $money1 = new Money(999); $money2 = new Money(1000); $money3 = new Money(1001); echo $accountant->isGreaterThan($money2, $money1); // true echo $accountant->isGreaterThan($money2, $money3); // false
小于
这是compare函数的包装函数。如果第一个Money
小于第二个Money
,则返回TRUE
。
@param Money @param Money @return bool $money1 = new Money(999); $money2 = new Money(1000); $money3 = new Money(1001); echo $accountant->isLessThan($money2, $money3); // true echo $accountant->isLessThan($money2, $money1); // false
等于
这是compare函数的包装函数。如果第一个Money
等于第二个Money
,则返回TRUE
。
@param Money @param Money @return bool $money1 = new Money(999); $money2 = new Money(1000); $money3 = new Money(1000); echo $accountant->isEqualTo($money2, $money3); // true echo $accountant->isEqualTo($money2, $money1); // false
测试
$ phpunit
贡献
请参阅CONTRIBUTING获取详细信息。
添加货币
我们使用生成器根据模板为每种个别货币创建类文件。要添加货币,编辑src/generator/CurrencyGenerator.php
文件,并将您的货币添加到currencies
类属性中。
致谢
许可
MIT许可(MIT)。有关更多信息,请参阅许可文件。