bentools/currency

PHP中的货币管理。

1.1 2019-07-19 09:52 UTC

This package is auto-updated.

Last update: 2024-09-18 16:42:41 UTC


README

Latest Stable Version License Build Status Coverage Status Quality Score Total Downloads

一个非常简单、框架无关的PHP库,用于处理货币。

安装

composer require bentools/currency:1.0.x-dev

示例使用

use BenTools\Currency\Converter\CurrencyConverter;
use BenTools\Currency\Model\Currency;
use BenTools\Currency\Provider\EuropeanCentralBankProvider;
use DateTime;

$eur = new Currency('EUR');
$usd = new Currency('USD');

$exchangeRateProvider = new EuropeanCentralBankProvider();
$exchangeRate = $exchangeRateProvider->getExchangeRate($eur, $usd, new DateTime('yesterday'));

$currencyConverter = new CurrencyConverter($exchangeRate);
var_dump($currencyConverter->convert(299, $usd, $eur)); // float(242.67510753997)
var_dump($currencyConverter->convert(10.99, $eur, $usd)); // float(13.540779)

bentools/currency 遵循SOLID原则。所以你可以自由实现自己的

  • CurrencyInterface(具有getCode()方法的简单值对象)
  • ExchangeRateInterface(具有源货币、目标货币和比率的值对象)
  • ExchangeRateFactoryInterface(如何实例化ExchangeRate对象)
  • ExchangeRateProviderInterface(提供实时或历史汇率)
  • CurrencyConverterInterface(用于将一种货币转换为另一种货币)

在线汇率提供商

我们为流行的API提供商提供适配器

  • 欧洲中央银行 - 无限制免费使用,以EUR为基础,支持约32种货币
  • Fixer.io* - 支持约170种货币,包括加密货币,免费计划基于EUR
  • CurrencyLayer.com* - 支持约170种货币,包括加密货币,免费计划基于USD
  • OpenExchangeRates.org* - 支持约200种货币,包括加密货币,免费计划基于USD

* 目前仅支持内置适配器中的免费计划。欢迎提交PR以支持付费计划。

链式汇率提供商

此提供商允许您链式使用提供者。第一个返回结果的就是赢家。

use BenTools\Currency\Model\Currency;
use BenTools\Currency\Provider\ChainedExchangeRateProvider;
use BenTools\Currency\Provider\CurrencyLayerProvider;
use BenTools\Currency\Provider\EuropeanCentralBankProvider;
use BenTools\Currency\Provider\FixerIOProvider;
use BenTools\Currency\Provider\OpenExchangeRatesProvider;

$eur = new Currency('EUR');
$usd = new Currency('USD');

$providers = [
    new EuropeanCentralBankProvider(),
    new OpenExchangeRatesProvider($openExchangeApiKey),
    new FixerIOProvider($fixerIoApiKey),
    new CurrencyLayerProvider($currencyLayerApiKey),
];

$exchangeRateProvider = new ChainedExchangeRateProvider($providers);
$exchangeRateProvider->getExchangeRate($eur, $usd);

平均汇率提供商

从不同提供者获取平均汇率。如果您提供容差,如果最低和最高汇率之间的差异超过它,将抛出异常。

use BenTools\Currency\Model\Currency;
use BenTools\Currency\Provider\AverageExchangeRateProvider;
use BenTools\Currency\Provider\CurrencyLayerProvider;
use BenTools\Currency\Provider\EuropeanCentralBankProvider;
use BenTools\Currency\Provider\FixerIOProvider;
use BenTools\Currency\Provider\OpenExchangeRatesProvider;
use DateTimeImmutable;

$eur = new Currency('EUR');
$usd = new Currency('USD');

$providers = [
    new EuropeanCentralBankProvider(),
    new OpenExchangeRatesProvider($openExchangeApiKey),
    new FixerIOProvider($fixerIoApiKey),
    new CurrencyLayerProvider($currencyLayerApiKey),
];

$tolerance = 0.005;
$exchangeRateProvider = AverageExchangeRateProvider::create($tolerance)->withProviders(...$providers);

$exchangeRateProvider->getExchangeRate($eur, $usd, new DateTimeImmutable('2018-03-29'))->getRatio();

PSR-16提供者

使用PSR-16装饰器缓存您的汇率,持续时间为您所选择的时间。

use BenTools\Currency\Model\Currency;
use BenTools\Currency\Provider\EuropeanCentralBankProvider;
use BenTools\Currency\Provider\PSR16CacheProvider;
use Redis;
use Symfony\Component\Cache\Simple\RedisCache;

$eur = new Currency('EUR');
$usd = new Currency('USD');

$redis = new Redis();
$redis->connect('localhost');
$ttl = 3600;
$provider = new PSR16CacheProvider(
    new EuropeanCentralBankProvider(), 
    new RedisCache($redis, 'currencies', $ttl)
);

$exchangeRate = $provider->getExchangeRate($eur, $usd);

Doctrine ORM提供者

如果您使用Doctrine ORM存储自己的汇率,内置实现可能有所帮助

use App\Entity\ExchangeRate;
use BenTools\Currency\Model\Currency;
use BenTools\Currency\Provider\DoctrineORMProvider;
use DateTimeImmutable;

$eur = new Currency('EUR');
$usd = new Currency('USD');

$exchangeRateProvider = new DoctrineORMProvider($doctrine, ExchangeRate::class);
$exchangeRateProvider->getExchangeRate($eur, $usd, new DateTimeImmutable('2018-03-29'))->getRatio();

框架无关

bentools/currency 利用 HttpPlug 连接到API。这意味着

  • 您可以使用项目中已存在的任何HTTP客户端(Guzzle 5,Guzzle 6,React,Zend,Buzz,...)
  • 默认情况下,bentools/currency 将自动发现要使用的客户端
  • 您可以在任何ExchangeRateProvider中通过其特定的配置强制使用特定的客户端。

请记住,大多数免费计划每月限制为1000次调用,因此您最好配置Http客户端缓存响应。如果您使用Guzzle 6+,请参阅 kevinrob/guzzle-cache-middleware

测试

./vendor/bin/phpunit

许可

MIT

免责声明

此库旨在易于使用,并旨在满足大多数常见需求。为此,它使用floats作为类型提示(但您可以自由存储为整数并转换回来)。

请注意,处理浮点数可能导致与大量数字处理相关的结果不准确。有关更多信息,请参阅 这里

$float = 0.1234567890123456789;
$factorA = 1000;
$factorB = 10000;

var_dump(($float * $factorA / $factorA) === $float); // true
var_dump(($float * $factorB / $factorB) === $float); // false

$integer = 1000000000000;
$factorA = 1000000;
$factorB = 10000000;
var_dump($integer * $factorA === (int) (float) ($integer * $factorA)); // true
var_dump($integer * $factorB === (int) (float) ($integer * $factorB)); // false

简而言之,当精度很重要时,使用此库时请避免处理大整数或高精度小数。