benjaminmal/exchangeratehost-bundle

ExchangeRate.host API for Symfony 的包

v1.0.0-beta6 2023-05-10 00:34 UTC

README

Continuous integration

exchangerate.host 包

此包允许您轻松地在 Symfony 应用程序中查询优秀的(并且免费!)exchangerate.host API。它支持 PSR-7PSR-17PSR-18,因此您可以完全控制您的依赖项!它还使用 Symfony 缓存

⚠️ 此包是非官方的。我与 exchangerate.host 无关。

摘要

需求

  • PHP ^8.1
  • Symfony ^6.2

安装

Composer

$ composer require benjaminmal/exchangeratehost-bundle

PSRs

为了使用此包,您需要设置 PSR-17 消息工厂和一个 PSR-18 HTTP 客户端。

如果您已经在您的服务中拥有 PSR-17 工厂和 PSR-18 HTTP 客户端,那么您已经完成了!否则,您可以使用这些出色的库

$ composer require nyholm/psr7 symfony/http-client

如果您正在使用 Symfony Flex 和推荐的库,那么您已经准备好了!

否则,通过将包添加到项目的 config/bundles.php 文件中注册的包列表中,来启用该包

// config/bundles.php

return [
    // ...
    Benjaminmal\ExchangeRateHostBundle\ExchangeRateHostBundle::class => ['all' => true],
];

然后添加您的 PSR-17PSR-18 服务实现(如果尚不存在的话)

# services.yaml
services:
    Psr\Http\Message\RequestFactoryInterface: '@your_custom_psr17_request_factory'
    Psr\Http\Message\UriFactoryInterface: '@your_custom_psr17_uri_factory'
    Psr\Http\Client\ClientInterface: '@your_custom_psr18_http_client'

入门

配置

以下文件是可选的,但以下是默认配置值

# exchangerate_host.yaml
exchangerate_host:
    cache:
        # Enabled / disable caching. Optional. Disabling it is not recommended 
        # (HTTP request can be long, rate limit could be hit).
        enabled: true
        
        # Set the cache pool. Optional. Set it to false if you don't want to use 
        # this specific cache pool. Default to "exchangeratehost.cache", which extends the default "app.cache".
        pools:
            latest_rates: 'exchangeratehost.cache'
            convert_currency: 'exchangeratehost.cache'
            historical_rates: 'exchangeratehost.cache'
            timeseries_rates: 'exchangeratehost.cache'
            fluctuation_data: 'exchangeratehost.cache'
            supported_currencies: 'exchangeratehost.cache'
            eu_vat_rates: 'exchangeratehost.cache'

使用 API 客户端

API 客户端可以通过自动装配通过 ExchangeRateHostClientInterface 或通过 benjaminmal.exchangerate_host_bundle.client 服务 ID 获取

namespace App\Service;

use Benjaminmal\ExchangeRateHostBundle\Client\ExchangeRateHostClientInterface;
use Benjaminmal\ExchangeRateHostBundle\Model\Option\ConvertCurrencyOption;
use Benjaminmal\ExchangeRateHostBundle\Model\Option\EuVatRatesOption;
use Benjaminmal\ExchangeRateHostBundle\Model\Option\FluctuationDataOption;
use Benjaminmal\ExchangeRateHostBundle\Model\Option\HistoricalRatesOption;
use Benjaminmal\ExchangeRateHostBundle\Model\Option\LatestRatesOption;
use Benjaminmal\ExchangeRateHostBundle\Model\Option\SupportedSymbolsOption;
use Benjaminmal\ExchangeRateHostBundle\Model\Option\TimeSeriesDataOption;
use Benjaminmal\ExchangeRateHostBundle\Model\Output\FluctuationData;
use Benjaminmal\ExchangeRateHostBundle\Model\Output\SymbolData;
use Benjaminmal\ExchangeRateHostBundle\Model\Output\VatRates;

class MyService
{
    public function __construct(private readonly ExchangeRateHostClientInterface $client)
    {
    }

    public function getLatestRates()
    {
        // Get the latest rates
        $rates = $this->client->getLatestRates(
            options: new LatestRatesOption( // Optional
                base: 'EUR',
                symbols: ['USD', 'CZK'],
                amount: 1200,
                places: 2,
                source: 'ecb',
                callback: 'functionName',
            ),
        );

        /**
         * @var string $currency
         * @var float $rate
         */
        foreach ($rates as $currency => $rate) {
            // ...
        }

        // ...
    }
    
    public function convertCurrency(): int
    {
        // Convert price
        /** @var int $newAmount */
        $newAmount = $this->client->convertCurrency(
            fromCurrency: 'EUR', // Required
            toCurrency: 'USD', // Required
            amount: 1300, // Required
            options: new ConvertCurrencyOption(), // Optional
        );
        
        // ...
    }
    
    public function getHistoricalRates()
    {
        // Get rates from a specific day
        $rates = $this->client->getHistoricalRates(
            date: new \DateTimeImmutable('-10days'), // Required, will be converted in the url with the format 'Y-m-d'
            options: new HistoricalRatesOption(), // Optional
        );
        
        /**
         * @var string $currency
         * @var float $rate
         */
        foreach ($rates as $currency => $rate) {
            // ...
        }
        
        // ...
    }
    
    public function getTimeSeriesRates()
    {
        // Get the rates between 2 dates
        $rates = $this->client->getTimeSeriesRates(
            startDate: new \DateTimeImmutable('-89days'), // Required
            endDate: new \DateTimeImmutable('-10days'), // Required
            options: new TimeSeriesDataOption(), // Optional
        );

        /**
         * @var $date string formatted as 'Y-m-d'
         * @var $datum iterable<string, float> 
         */
        foreach ($rates as $date => $datum) {
            foreach ($datum as $currency => $rate) {
                // ...
            }
        }

        // ...
    }
    
    public function getFluctuationData()
    {
        // Get the fluctuation data between 2 dates
        $data = $this->client->getFluctuationData(
            startDate: new \DateTimeImmutable('-89days'), // Required
            endDate: new \DateTimeImmutable('-10days'), // Required
            options: new FluctuationDataOption(), // Optional
        );
        
        /**
         * @var FluctuationData $fluctuationData 
         */
        foreach ($data as $currency => $fluctuationData) {
            echo $fluctuationData->startRate;
            echo $fluctuationData->endRate;
            echo $fluctuationData->change;
            echo $fluctuationData->changePct;
        }
        
        // ...
    }
    
    public function getCurrencies()
    {
        // Get the supported currencies
        $supportedCurrencies = $this->client->getSupportedCurrencies(
            options: new SupportedSymbolsOption(), // Optional
        );
        
        /**
         * @var SymbolData $supportedCurrency 
         */
        foreach ($supportedCurrencies as $currency => $supportedCurrency) {
            echo $supportedCurrency->code;
            echo $supportedCurrency->description;
        }
        
        // ...
    }
    
    public function getEurVatRates()
    {
        // Get EU VAT rates
        $rates = $this->client->getEuVatRates(
            options: new EuVatRatesOption(), // Optional
        );
        
        /**
         * @var VatRates $vatRate 
         */
        foreach ($rates as $countryCode => $vatRate) {
            echo $vatRate->countryName;
            echo $vatRate->standardRate;
            echo implode(', ', $vatRate->parkingRates);
            echo implode(', ', $vatRate->reducedRates);
            echo implode(', ', $vatRate->superReducedRates);
        }
    }
}

缓存

自定义缓存

您想要更改默认的缓存行为吗?让我们这样做

# exchangerate_host.yaml
exchangerate_host:
    cache:
        pools:
            latest_rates: 'my_new_pool.cache'
# cache.yaml
framework:
    cache:
        pools:
            my_new_pool.cache:
                adapter: exchangeratehost.cache # extending the default bundle cache
                defaultLifetime: 3600 # 1 hour
                # ... your custom config

清除缓存

如果您正在使用缓存(强烈推荐),您可能希望在每次新的 exchangerate.host API 条目时清除缓存。因此,您需要在每天凌晨 00:05 GMT 后在您的服务器上设置一个 cron 作业(在 FAQ 中找到)。

cron 命令

6 0 * * *

⚠️ Cron 通常在本地时间上工作!请根据您服务器所在的时区进行适配。

命令

php path/to/my_project/bin/console cache:pool:clear exchangeratehost.cache

如果您更改了默认的缓存池,请使用它们而不是 exchangeratehost.cache

还有更多?