maciej-sz/nbp-php

访问波兰国家银行(NBP - Narodowy Bank Polski)货币和商品汇率API

2.0.3 2024-08-06 22:19 UTC

This package is not auto-updated.

Last update: 2024-09-17 23:07:19 UTC


README

访问波兰国家银行(NBP - Narodowy Bank Polski)货币和商品汇率API。

Latest Version on Packagist Build Status Build Status No dependencies MIT License

用法

通过composer安装

composer require maciej-sz/nbp-php

最小设置

<?php
require_once 'vendor/autoload.php';

use MaciejSz\Nbp\Service\CurrencyAverageRatesService;

$currencyAverages = CurrencyAverageRatesService::new();
$rate = $currencyAverages->fromDay('2023-01-02')->fromTable('A')->getRate('USD');

printf('%s rate is %d', $rate->getCurrencyCode(), $rate->getValue());
USD rate is 4.381100

示例

本README中包含的所有工作示例均包含在存储库的examples/目录中。

服务

CurrencyAverageRatesService

此服务提供访问NBP表中发布的平均汇率的API。

fromMonth 方法

返回给定月份所有NBP表的汇率集合

$averageRatesFromJanuary = $currencyAverages->fromMonth(2023, 1);

foreach ($averageRatesFromJanuary as $rate) {
    printf(
        '%s rate from %s is %F' . PHP_EOL,
        $rate->getCurrencyCode(),
        $rate->getEffectiveDate()->format('Y-m-d'),
        $rate->getValue()
    );
}
THB rate from 2023-01-02 is 0.126700
USD rate from 2023-01-02 is 4.381100
AUD rate from 2023-01-02 is 2.976700
...

fromDay 方法

返回给定日期的NBP表字典。

$eurRateFromApril4th = $currencyAverages
    ->fromDay('2023-04-04')
    ->fromTable('A')
    ->getRate('EUR');

echo $eurRateFromApril4th->getValue(); // 4.6785

fromDayBefore 方法

返回给定日期前一天NBP表的字典。此方法在需要根据实际转账日期前一天的业务日汇率计算转账价格的一些会计应用中可能很有用。该法规要求使用实际转账日期前一个工作日的汇率来计算价格。这正是此方法所公开的。

示例

$eurRateFromBeforeJanuary2nd = $currencyAverages
    ->fromDayBefore('2023-01-02')
    ->fromTable('A')
    ->getRate('EUR')
;

printf(
    '%s rate from %s is %F',
    $eurRateFromBeforeJanuary2nd->getCurrencyCode(),
    $eurRateFromBeforeJanuary2nd->getEffectiveDate()->format('Y-m-d'),
    $eurRateFromBeforeJanuary2nd->getValue()
);
EUR rate from 2022-12-30 is 4.689900

getMonthTablesA 方法

返回特定月份的A表迭代器。这里的汇率按表分组,这些表代表NBP提供的实际数据结构。要获取汇率,需要进行第二次迭代

$aTablesFromMarch = $currencyAverages->getMonthTablesA(2023, 3);

foreach ($aTablesFromMarch as $table) {
    foreach ($table->getRates() as $rate) {
        printf(
            '%s rate from table %s is %F' . PHP_EOL,
            $rate->getCurrencyCode(),
            $table->getNo(),
            $rate->getValue()
        );
    }
}
THB rate from table 042/A/NBP/2023 is 0.126700
USD rate from table 042/A/NBP/2023 is 4.409400
AUD rate from table 042/A/NBP/2023 is 2.981900
...
THB rate from table 043/A/NBP/2023 is 0.126600
USD rate from table 043/A/NBP/2023 is 4.400200
AUD rate from table 043/A/NBP/2023 is 2.963800
...

获取特定汇率示例

$aTablesFromMarch = $currencyAverages->getMonthTablesA(2023, 3);

foreach ($aTablesFromMarch as $table) {
    $chfRate = $table->getRate('CHF');
    printf(
        '%s rate from table %s is %F' . PHP_EOL,
        $chfRate->getCurrencyCode(),
        $table->getNo(),
        $chfRate->getValue()
    );
}
CHF rate from table 042/A/NBP/2023 is 4.703100
CHF rate from table 043/A/NBP/2023 is 4.674300
CHF rate from table 044/A/NBP/2023 is 4.728000
// ...

getMonthTablesB 方法

返回特定月份的B表迭代器。

$bTablesFromMarch = $currencyAverages->getMonthTablesB(2022, 3);

foreach ($bTablesFromMarch as $table) {
    try {
        $rate = $table->getRate('MNT');
    } catch (CurrencyCodeNotFoundException $e) {
        continue;
    }
    printf(
        '%s rate from table %s is %F' . PHP_EOL,
        $rate->getCurrencyName(),
        $table->getNo(),
        $rate->getValue()
    );
}
tugrik (Mongolia) rate from table 009/B/NBP/2022 is 0.001500
tugrik (Mongolia) rate from table 010/B/NBP/2022 is 0.001529
tugrik (Mongolia) rate from table 011/B/NBP/2022 is 0.001469
tugrik (Mongolia) rate from table 012/B/NBP/2022 is 0.001457
tugrik (Mongolia) rate from table 013/B/NBP/2022 is 0.001417
关于表B中缺失货币的警告

在表B中可以有多个具有相同代码的货币。

也可能出现一种情况,即特定货币在一天表中出现,但在下一天表中没有出现。

在这种情况下,您不应使用getRate($rate)方法,而应迭代由getRates()返回的所有货币。

货币交易汇率服务

此服务用于从NBP表中获取买入和卖出汇率。

fromMonth 方法

返回整个月份的交易汇率。

$tradingRatesFromApril = $currencyTrading->fromMonth(2023, 4);

foreach ($tradingRatesFromApril as $rate) {
    printf(
        "%s rate from %s effective day traded on %s ask price is %s, bid price is %s\n",
        $rate->getCurrencyCode(),
        $rate->getEffectiveDate()->format('Y-m-d'),
        $rate->getTradingDate()->format('Y-m-d'),
        $rate->getAsk(),
        $rate->getBid()
    );
}
USD rate from 2023-04-03 effective day traded on 2023-03-31 ask price is 4.3338, bid price is 4.248
AUD rate from 2023-04-03 effective day traded on 2023-03-31 ask price is 2.9072, bid price is 2.8496
CAD rate from 2023-04-03 effective day traded on 2023-03-31 ask price is 3.2033, bid price is 3.1399
EUR rate from 2023-04-03 effective day traded on 2023-03-31 ask price is 4.7208, bid price is 4.6274
...

fromEffectiveDay 方法

返回有效日期的汇率。

$gbpFromApril4th = $currencyTrading->fromEffectiveDay('2023-04-04')->getRate('GBP');

printf(
    '%s rate from %s effective day traded on %s ask price is %s, bid price is %s',
    $gbpFromApril4th->getCurrencyCode(),
    $gbpFromApril4th->getEffectiveDate()->format('Y-m-d'),
    $gbpFromApril4th->getTradingDate()->format('Y-m-d'),
    $gbpFromApril4th->getAsk(),
    $gbpFromApril4th->getBid()
);
GBP rate from 2023-04-04 effective day traded on 2023-04-03 ask price is 5.3691, bid price is 5.2627

fromTradingDay 方法

返回交易日期的汇率。

$gbpFromApril4th = $currencyTrading->fromTradingDay('2023-04-04')->getRate('GBP');

printf(
    '%s rate from %s effective day traded on %s ask price is %s, bid price is %s',
    $gbpFromApril4th->getCurrencyCode(),
    $gbpFromApril4th->getEffectiveDate()->format('Y-m-d'),
    $gbpFromApril4th->getTradingDate()->format('Y-m-d'),
    $gbpFromApril4th->getAsk(),
    $gbpFromApril4th->getBid()
);
GBP rate from 2023-04-05 effective day traded on 2023-04-04 ask price is 5.4035, bid price is 5.2965

黄金汇率服务

此服务用于从NBP表中获取黄金商品汇率。

fromMonth 方法

获取特定月份的所有汇率。

$jan2013rates = $goldRates->fromMonth(2013, 1);

foreach ($jan2013rates as $rate) {
    printf(
        'Gold rate from %s is %F' . PHP_EOL,
        $rate->getDate()->format('Y-m-d'),
        $rate->getValue()
    );
}
Gold rate from 2013-01-02 is 165.830000
Gold rate from 2013-01-03 is 166.970000
Gold rate from 2013-01-04 is 167.430000
...

fromDay 方法

返回特定日期的黄金汇率。

$goldRateFromJan2nd2014 = $goldRates->fromDay('2014-01-02');

printf(
    'Gold rate from %s is %F',
    $goldRateFromJan2nd2014->getDate()->format('Y-m-d'),
    $goldRateFromJan2nd2014->getValue()
);
Gold rate from 2014-01-02 is 116.350000

fromDayBefore 方法

返回特定日期之前的黄金汇率。

$goldRateBeforeJan2nd = $goldRates->fromDayBefore('2014-01-02');

printf(
    'Gold rate from %s is %F',
    $goldRateBeforeJan2nd->getDate()->format('Y-m-d'),
    $goldRateBeforeJan2nd->getValue()
);
Gold rate from 2013-12-31 is 116.890000

使用缓存

请注意,必须提供实现PSR-6的库,才能使用缓存功能。

CachedTransport 类是所有其他传输实现的代理。此传输必须由另一个传输支持,因为它依赖于它来执行尚未缓存的请求。

示例

use Symfony\Component\Cache\Adapter\FilesystemAdapter as CachePoolAdapter;

// 1) create repository backed by caching transport
$cachePool = new CachePoolAdapter();
$cachingTransportFactory = CachingTransportFactory::new($cachePool);
$client = NbpWebClient::new(transportFactory: $cachingTransportFactory);
$nbpRepository = NbpWebRepository::new($client);

// 2) create needed services using cache-backed repository:
$goldRates = new GoldRatesService($nbpRepository);

// 3) run multiple times to check the effect of caching:
$start = microtime(true);
$goldRates->fromDayBefore('2013-05-15')->getValue();
$end = microtime(true);
$took = $end - $start;
printf('Getting the rate took %F ms', $took * 1000);

使用自定义传输

该库使用Symfony HTTP Client和Guzzle作为默认传输。如果这些包不可用,则回退到file_get_contents方法。在某些情况下,这可能不是理想的。特别是当使用PHP版本低于8.0时,无法访问HTTP客户端包。

在这种情况下,建议使用不同的传输。可以通过用您自己的实现替换NbpClientTransportFactory来实现。

$customTransportFactory = new class() implements TransportFactory {
    public function create(string $baseUri): Transport
    {
        return new class() implements Transport {
            public function get(string $path): array
            {
                echo "Requesting resource: {$path}" . PHP_EOL;

                $ch = curl_init();
                $url = NbpWebClient::BASE_URL . $path;
                curl_setopt($ch, CURLOPT_URL, $url);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                try {
                    $output = curl_exec($ch);
                } finally {
                    curl_close($ch);
                }

                echo 'Request successful' . PHP_EOL;

                return json_decode($output, true);
            }
        };
    }
};

$client = NbpWebClient::new(transportFactory: $customTransportFactory);
$nbpRepository = NbpWebRepository::new($client);
$goldRates = GoldRatesService::new($nbpRepository);

$rate = $goldRates->fromDay('2022-01-03');

printf(
    'Gold rate from %s is %F',
    $rate->getDate()->format('Y-m-d'),
    $rate->getValue()
);
Requesting resource: /api/cenyzlota/2022-01-01/2022-01-31
Request successful
Gold rate from 2022-01-03 is 235.720000

服务层

本服务包括对包的外观模式。由于“外观”一词通常指代访问系统内部的方式,因此这里的类命名为services而不是外观模式。

此层提供与NBP API交互的高级业务方法。它暴露了nbp-php包的常见用例,并且是使用此包的所有应用程序的起点。只有对于更复杂的任务,才需要与其它层交互。

服务层以直接与仓库层通信的方式构建。

仓库层

仓库层通过提供与NBP Web API紧密对应的方法来允许从NBP API获取数据。此层在更高级别上操作,使用的是填充的领域对象。

这里唯一的约束是,仓库层基于月份日期操作。例如,您可以获取整个月的交易汇率,但为了检索特定日期的数据,您必须遍历检索到的月份(您可以使用服务层来完成此操作)。这是为了减少与NBP服务器的网络流量而设计的。这也使得在传输层上简化缓存成为可能,因为不需要任何缓存池逻辑。

客户端层

客户端层是仓库层和传输层之间的桥梁。它在输入端处理请求对象,然后使用传输层来满足这些请求。

客户端层使用的请求比传输层上的请求高级。它们实现了NbpClientRequest接口。

传输层

传输层负责直接与NBP API交互。提供了一些独立的传输实现,用于服务对NBP API的连接。

它还配备了方便的工厂,根据安装的库和配置选择最合适的实现。