Mula 是一个 Laravel 扩展包,让安全处理货币变得非常简单!

v1.3.0 2023-02-03 12:06 UTC

This package is auto-updated.

Last update: 2024-08-30 01:17:50 UTC


README

Latest Version on Packagist Mula PhpUnit Tests Quality Score

Mula 是一个 Laravel 扩展包,让在应用中处理货币变得非常简单。它内部使用 Money for PHP,但去除了所有复杂性,并提供了您需要的所有组件,以便在几分钟内启动并运行货币处理。

Mula 完全不可变,因此您不会遇到更改您真正希望不更改的值的麻烦。它还处理舍入和分配,因此您不必担心任何财务丢失。

目录

安装

您可以通过 composer 安装此包

composer require lukeraymonddowning/mula

您应该运行以下命令发布 mula.php 配置文件:

php artisan vendor:publish --provider="Lukeraymonddowning\Mula\MulaServiceProvider"

基本用法和 API

我们提供了一个 Mula 门面,允许您轻松创建、解析和修改货币值。

创建

要手动创建新实例,请使用 create 方法。

Mula::create('12000', 'USD'); // $120.00

请注意,在创建时,我们排除了任何小数点。货币应传递为 ISO 4217 代码

您也可以省略货币,在这种情况下,Mula 将使用在 mula.php 配置文件中定义的默认货币,或者使用 .env 文件中的 MULA_CURRENCY 键。

虽然我们在文档中使用字符串将值传递给 create 方法,但您也可以传递整数。

解析

通常情况下,您会希望解析现有的货币值而不是从头创建新的货币值。当处理用户输入或从第三方 API 读取货币值时,应使用 parse 方法。

如果您使用的是 phpmoney 驱动(这是默认驱动),您有几种不同的解析货币的驱动可用。您可以在 mula.php 配置文件中设置所需的驱动程序,通过更改 mula.options.phpmoney.parser.default 的值。

我们建议使用默认的 aggregate 解析器,但为了清晰起见,我们将解释每个解析器的区别。

虽然我们在文档中使用字符串将值传递给 parse 方法,但您也可以传递整数或小数值。

聚合

默认的 aggregate 解析器是可用的最灵活的驱动程序,它会尝试解析以国际或十进制格式格式的货币字符串。以下是一些示例

Mula::parse('$120.99'); // $120.99

Mula::parse('120.99', 'USD'); // $120.99

Mula::parse('£120.99', 'USD'); // $120.99

Mula::parse('120', 'USD'); // $120.00

请注意,在第三个示例中,即使我们解析了一个英镑值,货币对象仍然是美元。这是因为我们传递了第二个参数 USD。传递货币将始终覆盖给定的货币。

国际

默认的 international 解析器将解析带有货币的完整货币字符串,但不会解析十进制字符串。

Mula::parse('$120.99'); // $120.99

Mula::parse('120.99'); // Exception

十进制

十进制解析器将解析给定货币(或默认货币)的十进制值,但不能解析货币字符串。

Mula::parse('120.99', 'USD'); // $120.99

Mula::parse('$120.99'); // Exception

显示

要在UI中显示货币,您可以使用display方法。它接受一个参数includeCurrency,该参数将决定结果中是否包含货币符号。

Mula::create('12099', 'USD')->display(); // $120.99

Mula::create('12099', 'USD')->display(false); // 120.99

Mula还实现了Stringable接口,因此您可以直接在blade视图中输出货币。

@php($money = Mula::create('12099', 'USD'))
<span>{{ $money }}</span>

{-- This will show as '$120.99' --}

无货币显示

作为一个语法上的便利,您可以使用displayWithoutCurrency方法,这是display(false)的一个别名。

货币

currency方法将返回货币对象的ISO 4217代码。

Mula::create('12099', 'USD')->currency(); // USD

Mula::create('12099', 'GBP')->currency(); // GBP

value方法将返回货币对象的非格式化值。您很少需要使用此方法,但Mula会使用它将值转换为数据库。

Mula::create('12099', 'USD')->value(); // 12099

添加

add方法将提供的货币对象添加到当前货币对象,并返回一个新的货币对象。您可以传递任意数量的货币对象作为变长参数。

Mula::create('1500', 'USD')->add(Mula::create('1500', 'USD'))->display(); // $30.00

Mula::create('1500', 'USD')->add(Mula::create('1500', 'USD'), Mula::create('3000', 'USD'))->display(); // $60.00

减去

subtract方法从当前货币对象中减去提供的货币对象,并返回一个新的货币对象。您可以传递任意数量的货币对象作为变长参数。

Mula::create('3000', 'USD')->subtract(Mula::create('1500', 'USD'))->display(); // $15.00

Mula::create('6000', 'USD')->subtract(Mula::create('1500', 'USD'), Mula::create('3000', 'USD'))->display(); // $15.00

乘以

multiplyBy方法将货币对象乘以给定的乘数,并返回一个新的货币对象。

Mula::create('5000', 'USD')->multiplyBy(2)->display(); // $100.00

除以

divideBy方法将货币对象除以给定的除数,并返回一个新的货币对象。

Mula::create('5000', 'USD')->divideBy(2)->display(); // $25.00

取模

mod方法返回在除以另一个货币总额后的余数。

Mula::create('1000', 'USD')->mod(Mula::create('300', 'USD'))->display(); // $1.00

与相同货币

要检查货币对象是否与其它货币对象具有相同的货币,请使用hasSameCurrencyAs方法。它接受任意数量的货币对象作为参数。如果任一参数具有不同的货币,则方法将返回false,否则返回true

Mula::create('1000', 'USD')->hasSameCurrencyAs(Mula::create('500', 'USD')); // TRUE

Mula::create('1000', 'USD')->hasSameCurrencyAs(Mula::create('500', 'GBP')); // FALSE

Mula::create('1000', 'USD')->hasSameCurrencyAs(Mula::create('500', 'USD'), Mula::create('3000', 'USD')); // TRUE

Mula::create('1000', 'USD')->hasSameCurrencyAs(Mula::create('500', 'USD'), Mula::create('3000', 'GBP')); // FALSE

等于

要检查货币对象是否等于其他货币对象,请使用equals方法。它接受任意数量的货币对象作为参数。如果任一参数的金额不同,则方法将返回false,否则返回true

Mula::create('1000', 'USD')->equals(Mula::create('1000', 'USD')); // TRUE

Mula::create('1000', 'USD')->equals(Mula::create('500', 'USD')); // FALSE

Mula::create('1000', 'USD')->equals(Mula::create('1000', 'USD'), Mula::create('1000', 'USD')); // TRUE

Mula::create('1000', 'USD')->equals(Mula::create('1000', 'USD'), Mula::create('500', 'USD')); // FALSE

大于

isGreaterThan方法检查货币对象是否大于所有其他货币对象。如果是,则返回true,如果提供的任何货币对象大于或等于它,则返回false

Mula::create('1000', 'USD')->isGreaterThan(Mula::create('999', 'USD')); // TRUE

Mula::create('1000', 'USD')->isGreaterThan(Mula::create('1000', 'USD')); // FALSE

Mula::create('1000', 'USD')->isGreaterThan(Mula::create('1500', 'USD')); // FALSE

Mula::create('1000', 'USD')->isGreaterThan(Mula::create('999', 'USD'), Mula::create('800', 'USD')); // TRUE

Mula::create('1000', 'USD')->isGreaterThan(Mula::create('1000', 'USD'), Mula::create('500', 'USD')); // FALSE

大于等于

isGreaterThanOrEqualTo方法检查货币对象是否大于等于所有其他货币对象。如果是,则返回true,如果提供的任何货币对象大于它,则返回false

Mula::create('1000', 'USD')->isGreaterThanOrEqualTo(Mula::create('999', 'USD')); // TRUE

Mula::create('1000', 'USD')->isGreaterThanOrEqualTo(Mula::create('1000', 'USD')); // TRUE

Mula::create('1000', 'USD')->isGreaterThanOrEqualTo(Mula::create('1500', 'USD')); // FALSE

Mula::create('1000', 'USD')->isGreaterThanOrEqualTo(Mula::create('999', 'USD'), Mula::create('800', 'USD')); // TRUE

Mula::create('1000', 'USD')->isGreaterThanOrEqualTo(Mula::create('1000', 'USD'), Mula::create('500', 'USD')); // TRUE

Mula::create('1000', 'USD')->isGreaterThanOrEqualTo(Mula::create('1000', 'USD'), Mula::create('1500', 'USD')); // FALSE

小于

isLessThan方法检查货币对象是否小于所有其他货币对象。如果是,则返回true,如果提供的任何货币对象小于或等于它,则返回false

Mula::create('1000', 'USD')->isLessThan(Mula::create('999', 'USD')); // FALSE

Mula::create('1000', 'USD')->isLessThan(Mula::create('1000', 'USD')); // TRUE

Mula::create('1000', 'USD')->isLessThan(Mula::create('1500', 'USD')); // TRUE

Mula::create('1000', 'USD')->isLessThan(Mula::create('1500', 'USD'), Mula::create('800', 'USD')); // FALSE

Mula::create('1000', 'USD')->isLessThan(Mula::create('1200', 'USD'), Mula::create('1500', 'USD')); // TRUE

小于等于

isLessThanOrEqualTo方法检查货币对象是否小于等于所有其他货币对象。如果是,则返回true,如果提供的任何货币对象小于它,则返回false

Mula::create('1000', 'USD')->isLessThanOrEqualTo(Mula::create('999', 'USD')); // FALSE

Mula::create('1000', 'USD')->isLessThanOrEqualTo(Mula::create('1000', 'USD')); // TRUE

Mula::create('1000', 'USD')->isLessThanOrEqualTo(Mula::create('1500', 'USD')); // TRUE

Mula::create('1000', 'USD')->isLessThanOrEqualTo(Mula::create('999', 'USD'), Mula::create('800', 'USD')); // FALSE

Mula::create('1000', 'USD')->isLessThanOrEqualTo(Mula::create('1000', 'USD'), Mula::create('500', 'USD')); // FALSE

Mula::create('1000', 'USD')->isLessThanOrEqualTo(Mula::create('1000', 'USD'), Mula::create('1500', 'USD')); // TRUE

分割

分割相对特殊。它根据提供的分配来分配货币。它可以接受一个integerarrayCollection,并返回一个包含MoneyCollection

如果您想尽可能均匀地将货币对象分割给一个给定的数字,请传递一个integer

Mula::create('10000', 'USD')->split(3); // A Collection. The first item will have a value of $33.34 the second and third items will have a value of $33.33. 

如果您想根据百分比分配货币,您可以传递一个包含数字的arrayCollection。这些值必须加起来等于100。

Mula::create('10000', 'USD')->split([30, 70]); // A Collection. The first item will have a value of $30.00 and the second item will have a value of $70.00.

Mula::create('10000', 'USD')->split(collect([30, 70])); // A Collection. The first item will have a value of $30.00 and the second item will have a value of $70.00.

在数据库中存储货币

Mula通过提供一个可以附加到您的Eloquent模型的自定义转换,使您能够轻松地将货币值存储和检索到数据库中。

use Illuminate\Database\Eloquent\Model;
use Lukeraymonddowning\Mula\Casts\Mula;

class Product extends Model {

    protected $casts = [
        'price' => Mula::class
    ];

}

数据库中存储货币值的列应该是字符串类型。这可以防止浮点数错误,同时也允许 Mula 将货币与值一起存储。

如果您希望将金额和货币存储在两个单独的列中,这样在执行数据库查询时您会有更多的自由度,您完全可以!只需在您的 $casts 数组中让 Mula 知道金额列和货币列分别是什么。

use Illuminate\Database\Eloquent\Model;
use Lukeraymonddowning\Mula\Casts\Mula;

class Product extends Model {

    protected $casts = [
        'price' => Mula::class.':amount,currency'
    ];

}

收集方法

Mula 为 Laravel Collections 添加宏,以便于对一组货币对象执行常见的货币操作。

财务总和

如果您需要将一组货币对象的 Collection 相加,可以使用 financialSum 方法。它将返回一个新的货币对象。

collect(Mula::create('1500', 'USD'), Mula::create('3000', 'USD'))->financialSum(); // A new money object with a value of $45.00.

测试

Mula 使用 PhpUnit 进行单元测试。您可以从终端运行测试套件。

composer test

更新日志

请参阅 更新日志 了解最近更改了哪些内容。

贡献

请参阅 贡献指南 了解详细信息。

安全

如果您发现任何安全问题,请通过发送电子邮件到 lukeraymonddowning@gmail.com 来报告,而不是使用问题跟踪器。

鸣谢

许可协议

MIT 许可协议 (MIT)。请参阅 许可文件 了解更多信息。

Laravel 包模板

此包使用 Laravel 包模板 生成。