定制 benjaminmal/exchangeratehost-bundle 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

benjaminmal/exchangeratehost-bundle

Composer 安装命令:

composer require benjaminmal/exchangeratehost-bundle

包简介

ExchangeRate.host API bundle for Symfony

README 文档

README

Continuous integration

exchangerate.host bundle

This bundle allows you to query the great (and free!) exchangerate.host API in a Symfony app with ease. It supports PSR-7, PSR-17, PSR-18 so you have full control of your dependencies! It uses also the Symfony Cache.

⚠️ This bundle is unofficial. I'm not related to exchangerate.host.

Summary

Requirements

  • PHP ^8.1
  • Symfony ^6.2

Installation

Composer

$ composer require benjaminmal/exchangeratehost-bundle

PSRs

In order to use this bundle, you need to set PSR-17 message factories and a PSR-18 HTTP client.

If you already have PSR-17 factories and PSR-18 HTTP client in your services you're done! Otherwise, you can use these great libraries:

$ composer require nyholm/psr7 symfony/http-client

If you're using Symfony Flex and the recommended librairies, you're all set!

Otherwise, enable the bundle by adding it to the list of registered bundles in the config/bundles.php file of your project:

// config/bundles.php

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

Then add your implementation of PSR-17 and PSR-18 services if they don't exist yet:

# 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'

Getting started

Config

The following file is optional but here are the default config values:

# 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'

Use the API client

The API client is available through autowiring via ExchangeRateHostClientInterface or via benjaminmal.exchangerate_host_bundle.client service 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);
        }
    }
}

Cache

Customizing the cache

You want to change the default cache behavior? Let's do that:

# 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

Clearing the cache

If you are using the cache (which is highly recommended) you may want to clear the cache at each new entry of the exchangerate.host API. So you need to set a cron job on your server just after 00:05am GMT everyday (found in the FAQ).

The cron command:

6 0 * * *

⚠️ Cron generally works on local time! Adapt it to the timezone of your servers.

The command:

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

If you changed the default cache pool, use them instead of exchangeratehost.cache!

What's more?

benjaminmal/exchangeratehost-bundle 适用场景与选型建议

benjaminmal/exchangeratehost-bundle 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 7 次下载、GitHub Stars 达 0, 最近一次更新时间为 2023 年 04 月 26 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 benjaminmal/exchangeratehost-bundle 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 benjaminmal/exchangeratehost-bundle 我们能提供哪些服务?
定制开发 / 二次开发

基于 benjaminmal/exchangeratehost-bundle 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 7
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 17
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2023-04-26