clippings / money-bundle
这是一个集成了 moneyphp/money 库(Fowler 模式)的 Symfony 包:https://github.com/moneyphp/money。
Requires
- php: >=5.5
- ext-curl: *
- composer/installers: ^1.5
- florianv/swap: ^3.2
- moneyphp/money: ^3.0
- php-http/guzzle6-adapter: ^1.1
- php-http/message: ^1.6
- symfony/console: ~2.8|~3.0
- symfony/dom-crawler: ~2.8|~3.0
- symfony/form: ~2.8|~3.0
- symfony/framework-bundle: ~2.8|~3.0
- symfony/twig-bundle: ~2.8|~3.0
Requires (Dev)
- ext-sqlite3: *
- beberlei/doctrineextensions: 0.3.*
- doctrine/doctrine-bundle: ~1.1
- doctrine/orm: ~2.3
- m6web/symfony2-coding-standard: ^3.3
- phpunit/dbunit: ~1.4
- phpunit/phpunit: ~4|~5
- squizlabs/php_codesniffer: ^2.7
- symfony/browser-kit: ~2.8|~3.0
- symfony/class-loader: ~2.8|~3.0
- symfony/finder: ~2.8|~3.0
- symfony/phpunit-bridge: ~2.8|~3.0
- symfony/yaml: ~2.8|~3.0
Suggests
- doctrine/doctrine-bundle: ~1.1
- doctrine/orm: ~2.3
- v4.0.0-beta.4
- v4.0.0-beta.3
- v4.0.0-beta.2
- v4.0.0-beta.1
- 3.x-dev
- v3.1.3
- v3.1.2
- v3.1.1
- v3.1.0
- v3.0.0
- 2.x-dev
- v2.7.1
- v2.7.0
- v2.6.0
- v2.5.0
- 2.4.0
- v2.3.1
- v2.3.0
- v2.2.0
- v2.1.1
- v2.1.0
- v2.0.1
- v2.0.0
- v1.4.0
- v1.3.0
- v1.2.0
- v1.1.0
- v1.0.0
- dev-upstream-sync
- dev-feature_money_3
- dev-fix_empty_data
- dev-symfony3-migration
This package is not auto-updated.
Last update: 2023-01-26 13:44:42 UTC
README
此包用于将 mathiasverraes 的 Money 库 集成到 Symfony 项目中。
此库基于 Fowler 的 Money 模式
- 此包已在 Symfony 2.8 和 Symfony 3.1 上进行测试,并且稳定。
快速开始
use Money\Money; use Tbbc\MoneyBundle\Form\Type\MoneyType; // the money library $fiveEur = Money::EUR(500); $tenEur = $fiveEur->add($fiveEur); list($part1, $part2, $part3) = $tenEur->allocate(array(1, 1, 1)); assert($part1->equals(Money::EUR(334))); assert($part2->equals(Money::EUR(333))); assert($part3->equals(Money::EUR(333))); // a service that stores conversion ratios $pairManager = $this->get('tbbc_money.pair_manager'); $usd = $pairManager->convert($tenEur, 'USD'); // a form integration $formBuilder->add('price', MoneyType::class);
功能
- 集成 mathiasverraes 的 money 库
- 模板中处理货币和货币单位的 Twig 过滤器和 PHP 辅助函数
- 货币比率的存储系统
- 从外部 API 获取比率的 ratioProvider 系统
- Symfony 表单集成
- 不同的操作控制台命令
- 用于指定网站使用的货币的配置解析器
- 获取已获取的货币比率的记录
- 货币格式化 i18n
目录
安装
使用 Composer 并安装 $ composer require tbbc/money-bundle
然后在 AppKernel 中添加包
public function registerBundles() { $bundles = array( // ... new Tbbc\MoneyBundle\TbbcMoneyBundle(), ); }
在您的 config.yml 中,添加您想使用的货币和参考货币。
tbbc_money: currencies: ["USD", "EUR"] reference_currency: "EUR" decimals: 2
在您的 config.yml 中,添加表单字段呈现
twig: form: resources: - 'TbbcMoneyBundle:Form:fields.html.twig'
您还应注册自定义 Doctrine Money 类型
doctrine: dbal: types: money: Tbbc\MoneyBundle\Type\MoneyType
使用
Money 库集成
use Money\Money; $fiveEur = Money::EUR(500); $tenEur = $fiveEur->add($fiveEur); list($part1, $part2, $part3) = $tenEur->allocate(array(1, 1, 1)); assert($part1->equals(Money::EUR(334))); assert($part2->equals(Money::EUR(333))); assert($part3->equals(Money::EUR(333))); $pair = new CurrencyPair(new Currency('EUR'), new Currency('USD'), 1.2500); $usd = $pair->convert($tenEur); $this->assertEquals(Money::USD(1250), $usd);
表单集成
您有 3 种新的表单类型(在 Tbbc\MoneyBundle\Form\Type 命名空间下)
- CurrencyType : 在 config.yml 中定义的货币中选择一种货币
- MoneyType : 请求金额和货币
- SimpleMoneyType : 请求金额并将货币设置为 config.yml 中设置的参考货币
示例
use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; // I create my form $form = $this->createFormBuilder() ->add('name', TextType::class) ->add('price', MoneyType::class, [ 'data' => Money::EUR(1000), //EUR 10 ]) ->add('save', SubmitType::class) ->getForm();
使用 Doctrine 存储货币
解决方案 1 : 数据库中的两个字段
请注意,数据库表中有两个列:$priceAmount 和 $priceCurrency,并且只有一个 getter/setter:getPrice 和 setPrice。
get/setPrice 方法处理这两个列。
- 优点:您的数据库是干净的,您可以在数据库中通过两个不同的列进行 sql sum、group by、sort 等。
- 缺点:实体中看起来很丑。
<?php namespace App\AdministratorBundle\Entity; use Doctrine\ORM\Mapping as ORM; use Money\Currency; use Money\Money; /** * TestMoney * * @ORM\Table("test_money") * @ORM\Entity */ class TestMoney { /** * @var integer * * @ORM\Column(type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @var integer * * @ORM\Column(name="price_amount", type="integer") */ private $priceAmount; /** * @var string * * @ORM\Column(name="price_currency", type="string", length=64) */ private $priceCurrency; /** * Get id * * @return integer */ public function getId() { return $this->id; } /** * get Money * * @return Money */ public function getPrice() { if (!$this->priceCurrency) { return null; } if (!$this->priceAmount) { return new Money(0, new Currency($this->priceCurrency)); } return new Money($this->priceAmount, new Currency($this->priceCurrency)); } /** * Set price * * @param Money $price * @return TestMoney */ public function setPrice(Money $price) { $this->priceAmount = $price->getAmount(); $this->priceCurrency = $price->getCurrency()->getCode(); return $this; } }
解决方案 2:使用 Doctrine 类型
您的数据库表只有一个字符串列。货币对象由新的 Doctrine 类型手动序列化。
1.25€ 在您的数据库中序列化为 'EUR 125'。 这种格式是稳定的,未来的版本中不会改变。
新的 Doctrine 类型名称为 "money"。
- 优点:实体易于创建和使用
- 缺点:直接使用 SQL 请求数据库较为困难。
<?php namespace App\AdministratorBundle\Entity; use Doctrine\ORM\Mapping as ORM; use Money\Money; /** * TestMoney * * @ORM\Table("test_money") * @ORM\Entity */ class TestMoney { /** * @var integer * * @ORM\Column(type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @var Money * * @ORM\Column(name="price", type="money") */ private $price; /** * Get id * * @return integer */ public function getId() { return $this->id; } /** * get Money * * @return Money */ public function getPrice() { return $this->price; } /** * Set price * * @param Money $price * @return TestMoney */ public function setPrice(Money $price) { $this->price = $price; return $this; } }
转换管理器
将金额转换为另一种货币
$pairManager = $this->get("tbbc_money.pair_manager"); $usd = $pairManager->convert($amount, 'USD');
在数据库中保存转换值
use Money\Money; $pairManager = $this->get("tbbc_money.pair_manager"); $pairManager->saveRatio('USD', 1.25); // save in ratio file in CSV $eur = Money::EUR(100); $usd = $pairManager->convert($amount, 'USD'); $this->assertEquals(Money::USD(125), $usd);
货币格式化器
<?php namespace My\Controller\IndexController; use Money\Money; use Money\Currency; class IndexController extends Controller { public function myAction() { $moneyFormatter = $this->get('tbbc_money.formatter.money_formatter'); $price = new Money(123456789, new Currency('EUR')); // best method (added in 2.2+ version) \Locale::setDefault('fr_FR'); $formatedPrice = $moneyFormatter->localizedFormatMoney($price); // 1 234 567,89 € $formatedPrice = $moneyFormatter->localizedFormatMoney($price, 'en'); // €1,234,567.89 // old method (before v2.2) $formattedPrice = $moneyFormatter->formatMoney($price); // 1 234 567,89 $formattedCurrency = $moneyFormatter->formatCurrency($price); // € } }
Twig 集成
{{ $amount | money_localized_format('fr') }} => 1 234 567,89 € {{ $amount | money_localized_format('en_US') }} => €1,234,567.89 {{ $amount | money_localized_format }} => depends on your default locale {{ $amount | money_format }} {{ $amount | money_as_float }} {{ $amount.currency | currency_symbol }} {{ $amount.currency.code }} {{ $amount | money_convert("USD") | money_format }} {{ $amount | money_format_currency }}
PHP 模板集成
<span class="price"><?php echo $view['tbbc_money']->format($price) ?></span> <span class="money"><?php echo $view['tbbc_money_currency']->formatCurrencyAsSymbol($price->getCurrency()) ?></span>
从远程提供程序获取汇率值
# save a ratio in the storage ./bin/console tbbc:money:ratio-save USD 1.25 # display ratio list ./bin/console tbbc:money:ratio-list # fetch all the ratio for all defined currencies from an external API ./bin/console tbbc:money:ratio-fetch
更改汇率提供程序
此捆绑包使用 florianv/swap 库从 各种提供程序请求货币汇率。
汇率提供程序使用 Yahoo 财经提供程序。您可以在 config.yml 文件中更改提供程序。
tbbc_money:
[...]
ratio_provider: "google_provider"
在这里 google_provider
是您在使用之前需要使用依赖注入定义的服务名称,例如
services:
curl:
class: Ivory\HttpAdapter\CurlHttpAdapter
google_provider:
class: Swap\Provider\GoogleFinanceProvider
arguments:
- "@curl"
您可以使用 florianv/swap 项目中描述的任何提供程序,甚至这些提供程序的组合。以下示例将尝试使用 Yahoo 提供程序,如果失败,则切换到 Google 提供程序
services:
curl:
class: Ivory\HttpAdapter\CurlHttpAdapter
yahoo_provider:
class: Swap\Provider\YahooFinanceProvider
arguments:
- "@curl"
google_provider:
class: Swap\Provider\GoogleFinanceProvider
arguments:
- "@curl"
chain_provider:
class: Swap\Provider\ChainProvider
arguments:
- ["@yahoo_provider", "@google_provider"]
tbbc_money:
[...]
ratio_provider: "chain_provider"
创建自己的汇率提供程序
汇率提供程序是一个实现了 Swap\ProviderInterface
接口的服务。我建议您阅读接口的 PHP 文档,以了解如何实现新的汇率提供程序。
新的汇率提供程序必须注册为服务。
要使用新的汇率提供程序,您应该在 config.yml 中设置要使用的服务,并提供服务名称。
tbbc_money:
[...]
ratio_provider: your_provider_service
自动货币汇率抓取
将其添加到您的 crontab 中
1 0 * * * /my_app_dir/bin/console tbbc:money:ratio-fetch > /dev/null
MoneyManager:从浮点数创建货币对象
从浮点数创建货币对象可能有点棘手,因为存在舍入问题。
<?php $moneyManager = $this->get("tbbc_money.money_manager"); $money = $moneyManager->createMoneyFromFloat('2.5', 'USD'); $this->assertEquals("USD", $money->getCurrency()->getCode()); $this->assertEquals(250, $money->getAmount());
使用 pairHistoryManager 获取货币汇率历史
使用此功能需要 Doctrine。
为了获取汇率历史,您必须在配置中启用它并使用 Doctrine。
tbbc_money: currencies: ["USD", "EUR"] reference_currency: "EUR" enable_pair_history: true
然后您可以使用以下服务
$pairHistoryManager = $this->get("tbbc_money.pair_history_manager"); $dt = new \DateTime("2012-07-08 11:14:15.638276"); // returns ratio for at a given date $ratio = $pairHistoryManager->getRatioAtDate('USD',$dt); // returns the list of USD ratio (relative to the reference value) $ratioList = $pairHistoryManager->getRatioHistory('USD',$startDate, $endDate);
RatioStorage
有两个存储汇率的方法:CSV 文件或 Doctrine。默认情况下,TbbcMoneyBundle 使用 CSV 文件。
如果您想切换到 Doctrine 存储,请编辑您的 config.yml
tbbc_money: storage: doctrine
更新您的数据库模式
./bin/console doctrine:schema:update --force
使用Doctrine存储,货币比率将使用默认的实体管理器,并将数据存储在 tbbc_money_doctrine_storage_ratios 中。
MoneyFormatter 中的自定义 NumberFormatter
MoneyFormatter::localizedFormatMoney(服务 'tbbc_money.formatter.money_formatter')使用 php NumberFormatter 类(https://php.ac.cn/manual/en/numberformatter.formatcurrency.php)来格式化货币。
您可以
- 将您自己的 \NumberFormatter 实例作为 MoneyFormatter::localizedFormatMoney 的参数
- 继承 MoneyFormatter 并重写 getDefaultNumberFormater 方法以设置全局 NumberFormatter
在不使用 Doctrine 的情况下使用 TbbcMoneyBundle
您必须禁用对偶历史服务,才能在不使用 Doctrine 的情况下使用 TbbcMoneyBundle。
tbbc_money:
enable_pair_history: true
注意:您可以考虑编写自己的 PairHistoryManager 以用于 MongoDB 或 Propel,这非常容易实现。不要犹豫,提交带有您代码和测试的 PR。
优化
在您的 config.yml 中,您可以
- 选择要使用的模板引擎。默认情况下,只加载了 Twig。
- 定义单位后面的位数(例如:12.25€:2位小数;11.5678€:4位小数)
tbbc_money: currencies: ["USD", "EUR"] reference_currency: "EUR" decimals: 2 enable_pair_history: true ratio_provider: tbbc_money.ratio_provider.yahoo_finance
关于旧版本的说明
- 上面的示例使用 Symfony 3 语法进行控制台操作(
./bin/console
),对于 2.8 版本,您应使用./app/console
代替。 - "class" 常量(例如
MoneyType::class
)仅从 PHP 5.5 开始支持,如果您使用的是旧版本,则应使用完整的类名(例如Tbbc\MoneyBundle\Type\MoneyType
)
贡献
- 查看 问题列表。
- 分支
- 编写测试(用于新功能或错误)
- 创建 PR
需求
- PHP 5.3.9+
- Symfony 2.8+
作者
Philippe Le Van - kitpages.fr - twitter:@plv Thomas Tourlourat - Wozbe - twitter:@armetiz
状态
稳定
什么是功能性的
- 货币库的集成
- 配置解析器
- 对偶管理器
- Travis CI 集成
- 表单集成
- 表单的 Twig 展示
- Twig 过滤器
- 创建和显示比率的命令
- 自动获取比率(使用 2 个比率提供程序)
- 货币比率的记录