browner12/money

此包已被 废弃 并不再维护。作者建议使用 moneyphp/money 包代替。

PHP 的货币值对象

v1.0.2 2015-12-06 02:21 UTC

This package is auto-updated.

Last update: 2019-02-20 19:26:12 UTC


README

此包已被 ABANDONED。我们终于有一个好的社区货币包了,所以请查看 money/money

此存储库于 2017 年 5 月 23 日被标记为 ABANDONED。它将一直可用到 2018 年 5 月 23 日。请在那时之前将此代码从您的项目中重构。

谢谢!

money

Latest Version Software License Build Status Total Downloads

这是一个针对 PHP 的货币包。它包括一个 Money、一个 Currency 和一个 Accountant。理解这三个类之间的区别很重要。这些类之间的关系使得这个包与一些现有的 PHP 货币包不同。Money 由两个属性组成:一个数值和一个 CurrencyCurrency 是一个描述符。它对值一无所知,但为 Money 提供描述值所需的信息。Accountant 处理您的 Money。他可以对您的 Money 执行许多计算,包括添加、减去、求和、分配、计算税率等。

理解 Money 持有的值非常重要。Currency 有基本单位和子单位。对于美元,基本单位是美元。子单位是分。在内部,Money 以子单位跟踪其值。虽然您可以通过传递基本单位或子单位来创建一个 Money 对象,但我们默认假设您传递的是子单位。有关如何更改此假设的文档,请参阅下面的文档。

注意:Accountant 只能对同一 Currency 的多个 Money 执行操作。不同的 Currency 将抛出异常。如果您想将一个 Currency 转换为另一个,请使用 Accountantexchange() 方法。您必须提供汇率。

谁应该使用此包

如果您正在运行电子商务网站并自行处理购物车和支付,请使用此包。此包提供了许多辅助函数,使计算行总计、税费、小计和总计变得非常简单。

谁不应该使用此包

如果您需要比货币的子单位更高的精度,请不要使用此包。例如,在金融界,美元通常跟踪到千分之一(4 位小数)。这相当于 1/100 分(子单位)。此包处理的最小值是货币的 1 个子单位,任何比 1 个子单位更精确的值都将四舍五入。

小心

请注意您的系统是 32 位或 64 位架构,因为这决定了您可以表示的最大整数值。对于 32 位,这是 2147483647,对于 64 位,这是 9223372036854775807。无论如何,对于大多数基数 100 的货币,这通常不会成为问题,除非您正在处理大量资金(数百万),但这是一件需要注意的事情。

PSRs

此包遵循 PSR-1 和 PSR-4。所有贡献都应遵循这些。

影响

本包受到了 sebastianbergmann/moneymathiasverraes/money 的影响。我确实喜欢这些包的某些部分,但也有一些我不喜欢的部分,所以我决定自己制作。具体来说,我认为这个包有更好的类布局和组织,类的之间的关系更准确地反映了现实世界。我还认为这个包通过 Accountant 类更好地遵循了 SRP(单一责任原则)。在其他包中,Money 类承担了太多的责任,包括执行计算。在这个包中,Money 只负责知道它的值和 Currency,而 Accountant 负责执行计算。

安装

通过 Composer

$ composer require browner12/money

文档

有 3 个类可以操作:CurrencyMoneyAccountant。我们将逐一介绍。

对于所有文档,以下假设成立

  • 使用 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仅强制执行getQuantitygetUnitPrice契约。以下示例中,我们假设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)。有关更多信息,请参阅许可文件