yceruto / money-bundle
Money PHP 的 Symfony 扩展包
Requires
- php: >=8.1
- moneyphp/money: ^4.1
- symfony/config: ^5.4|^6.0|^7.0
- symfony/dependency-injection: ^5.4|^6.0|^7.0
- symfony/http-kernel: ^5.4|^6.0|^7.0
Requires (Dev)
- ext-gmp: *
- ext-intl: *
- doctrine/doctrine-bundle: ^2.8
- doctrine/orm: ^2.14
- phpunit/phpunit: ^9.5
- psalm/plugin-phpunit: ^0.18.4
- psalm/plugin-symfony: ^5.0
- roave/security-advisories: dev-latest
- symfony/form: ^6.2
- symfony/twig-bridge: ^6.2
- twig/twig: ^3.5
- vimeo/psalm: ^5.4
README
Symfony 集成 https://github.com/moneyphp/money 库。有关 MoneyPHP 库如何工作的更多信息,请参阅其官方文档 https://www.moneyphp.org。
目录
安装
此扩展包与 PHP 8.1 及以上版本兼容,以及 Symfony 5.4 及更高版本。
$ composer require yceruto/money-bundle
如果您不使用 symfony/flex
,请确保将扩展包添加到 config/bundles.php
文件中。这将确保它被正确注册,并可以在您的应用程序中使用。
货币
应用程序通常需要来自不同数据源的具体货币子集。为此,您可以实现 Money\Currencies
接口,该接口提供可用货币列表和每种货币的子单位。
以下货币类作为服务可用
- Money\Currencies\Currencies (AggregateCurrencies 的别名)
- Money\Currencies\CurrencyList
- Money\Currencies\ISOCurrencies
- Money\Currencies\BitcoinCurrencies
- Money\Currencies\CryptoCurrencies
Currencies
接口是 Money\Currencies\AggregateCurrencies
服务的别名,该服务包含默认的货币提供者。
提供者按指定顺序注入到 AggregateCurrencies
服务中。如果您想添加更多提供者,则需要实现 Money\Currencies
接口并使用 money.currencies
标签服务。
Money\Currencies\CurrencyList
提供者从 money 配置中检索货币
# config/packages/money.yaml money: currencies: FOO: 2
该列表由货币代码(字符串)和子单位(整数)的配对组成。您还可以使用此配置覆盖 Money\Currencies\ISOCurrencies
的子单位。
在许多情况下,您可能不知道将要格式化或解析的确切货币。对于这些场景,我们提供了一种聚合格式化和解析服务,允许您配置多个格式化/解析器,然后根据值选择最合适的一个。您可以在格式化和解析部分找到更多关于此的信息。
格式化
货币格式化器在您需要以特定格式显示货币值时非常有用。它们允许将货币对象转换为人类可读的字符串,从而更容易向用户展示财务数据。通过使用格式化器,您可以确保显示的货币值清晰易懂。
以下格式化器类作为服务可用
- Money\Formatter\MoneyFormatter (AggregateMoneyFormatter 的别名)
- Money\Formatter\IntMoneyFormatter (如果启用了 Intl 扩展,则为默认值)
- Money\Formatter\IntLocalizedMoneyFormatter (如果启用了 Intl,则可用)
- Money\Formatter\DecimalMoneyFormatter (如果未启用 Intl 扩展,则为默认值)
- Money\Formatter\BitcoinMoneyFormatter (适用于
XBT
货币代码)
您可以使用 Money\MoneyFormatter
接口作为任何服务的依赖项,因为它是一个别名,代表 Money\Formatter\AggregateMoneyFormatter
服务,并附带默认格式化器。
使用以下配置设置当前格式化器的默认值
# config/packages/money.yaml money: formatters: intl: number_locale: 'en_US' number_style: 2 # \NumberFormatter::CURRENCY number_pattern: null bitcoin: fraction_digits: 8
在 Symfony 请求期间,货币格式化器将考虑当前请求的区域设置来格式化货币对象。这确保了格式化输出是本地化的,并且适合用户的位置。
要注册自定义格式化程序,您需要实现Money\MoneyFormatter
接口,并将服务标记为money.formatter
以及格式化程序支持的货币code
属性。这将允许您使用自定义格式化程序来格式化特定货币的货币值。如果您的新的格式化程序支持任何货币,可以将code
属性设置为*
。这将允许格式化程序用于任何货币。
解析
货币解析器可以帮助自动化从文本中提取货币值的过程,使其更高效、更准确。
以下解析器类作为服务可用:
Money\Parser\MoneyParser
(AggregateMoneyParser
的别名)Money\Parser\IntMoneyParser
(如果启用Intl扩展,则为默认值)Money\Parser\IntLocalizedDecimalParser
(如果启用Intl,则可用)Money\Parser\DecimalMoneyParser
(如果未启用Intl扩展,则为默认值)Money\Parser\BitcoinMoneyParser
(适用于XBT
货币代码)
您可以将Money\MoneyParser
接口作为任何服务的依赖项使用,因为它是对Money\Parser\AggregateMoneyParser
服务的别名,并附带默认解析器。
要注册自定义解析器,您应实现Money\MoneyParser
接口,并将服务标记为money.parser
。这将使您能够使用自定义解析器从给定文本中解析货币值。
货币转换
要将Money
实例从一个货币转换为另一个货币,您需要使用Money\Converter
服务。此类依赖于Currencies
和Exchange
服务。服务返回一个CurrencyPair
,表示基础货币、对立货币和转换比率。
以下交换类作为服务可用:
Money\Exchange
(FixedExchange
的别名)Money\Exchange\FixedExchange
Money\Exchange\IndirectExchange
Money\Exchange\ReversedCurrenciesExchange
在某些情况下,您可能希望Money\Converter
服务还解决给定CurrencyPair
的反向,如果原始货币对无法找到。为此,您可以注入Converter $reversedConverter
参数,它是money.reversed_converter
服务的别名。如果找到反向CurrencyPair
,则将其用作1
的除数来计算反向转换比率。
要配置Money\Exchange\FixedExchange
服务,您可以使用以下配置:
# config/packages/money.yaml money: exchanges: fixed: EUR: USD: '1.10'
注意:与第三方服务(如Swap和Exchanger)的集成目前不在本包的范围内。
数据传输对象
按设计,Money\Money
值对象是不可变的,这意味着创建后无法更改原始金额和货币值。为了解决这个问题,本包提供了一个名为MoneyDto
的DTO模型,可用于各种情况,如用户输入、API请求、表单处理、验证等。此模型允许您修改金额和货币值,这在需要更改这些值以创建新的Money\Money
实例的场合非常有用。
$dto = new MoneyDto(); // default null for amount and currency properties $dto = MoneyDto::fromMoney(Money::EUR(100)); // returns a new DTO instance $dto = MoneyDto::fromAmount(100); // default EUR currency $dto = MoneyDto::fromCurrency('USD'); // default 0 amount $money = $dto->toMoney(); // returns a new Money\Money instance
其他集成
表单
Symfony MoneyType
将更新为从currency
值推导出scale
和divisor
选项。
$formBuilder->add('price', MoneyType::class, ['currency' => 'CUP'])
与典型用法相反,它不应直接与Money\Money
对象一起使用。相反,它期望与该表单字段关联一个数值属性。
您可以通过修改配置来禁用此集成。
# config/packages/money.yaml money: form: enabled: false
Twig
如果您已将twig/twig
作为模板引擎安装,则可以使用提供的Twig过滤器在任何模板页面上直接格式化货币对象。
{{ money|money_format }}
它将遵循与Money\Formatter\MoneyFormatter
服务相同的行为。
您可以通过修改配置来禁用此集成。
# config/packages/money.yaml money: twig: enabled: false
Doctrine
Doctrine 允许您使用 Embedded
属性将嵌入对象映射到数据库列,并且这个扩展包提供了用于 Doctrine 扩展包的 Money\Money
ORM 映射定义(如果已启用)。这意味着您可以使用 Doctrine 的实体管理器来持久化和检索具有嵌入货币值的实体,而无需手动配置 ORM 映射。这可以简化您的开发过程,并使您能够专注于应用程序的其他方面。
use Doctrine\ORM\Mapping\Embedded; use Money\Money; class Product { #[Embedded] private Money $price; }
重要提示:为确保正确处理 Money\Money
映射,请在注册 DoctrineBundle
之前在 bundles.php
中注册此扩展包。
// config/bundles.php return [ // ... Yceruto\MoneyBundle\MoneyBundle::class => ['all' => true], Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true], // ... ];
您还可以在 DQL(Doctrine 查询语言)查询中使用已通过 Doctrine 映射的嵌入类字段。这些字段可以像在 Product 类中声明一样使用。
SELECT p FROM Product p WHERE p.price.amount > 1000 AND p.price.currency.code = 'EUR'
您可以通过修改配置来禁用此集成。
# config/packages/money.yaml money: doctrine: enabled: false
许可证
本软件根据 MIT 许可证 发布。