Symfony Swap
Drop-in Symfony bundle for currency conversion: configurable services, multi-provider exchange rates with fallback and caching.
Install / Use
npx skills add florianv/symfony-swapInstalls into whichever agent you are using.
README
Symfony Swap
<table> <tr> <td width="220" align="center"> <a href="https://www.fastforex.io" target="_blank" rel="noopener"> <img src="https://console.fastforex.io/img/fastforex/logo-bk-1k.svg" width="180px" alt="fastFOREX"/> </a> </td> <td> <strong>Sponsored by <a href="https://www.fastforex.io" target="_blank" rel="noopener">fastFOREX</a>.</strong> Real-time JSON API, 160+ currencies, 55+ years of history, 500+ cryptocurrencies. <strong>Free tier</strong>; paid plans from $18/month. <a href="https://www.fastforex.io" target="_blank" rel="noopener"><strong>→ Get a free fastFOREX API key</strong></a> </td> </tr> </table>Drop-in Symfony bundle for currency conversion. Multi-provider exchange rates with fallback, caching, and Symfony Cache integration. Maintained since 2014.
Install the bundle, drop a florianv_swap.yaml in config/packages/, and the florianv_swap.swap service is ready to inject. No service container plumbing, no boilerplate.
Symfony Swap is a drop-in package for Symfony currency conversion. Install it, configure providers in config/packages/florianv_swap.yaml, and pull exchange rates from multiple providers in one call. The bundle integrates with Symfony Cache out of the box and supports Symfony 6.4 / 7 / 8.
💡 What is Symfony Swap?
- The Symfony integration of Swap, the PHP currency conversion library.
- Registers a
florianv_swap.swapservice in the container (Swap\Swapclass). - Configuration lives in
config/packages/florianv_swap.yaml. - Caching uses Symfony Cache (
array,apcu,filesystem, or any PSR-16 service ID). - Providers are tried in priority order (higher priority first).
📦 Installation
Symfony Swap requires PHP 8.2 or newer and Symfony 6.4, 7, or 8.
composer require florianv/swap-bundle symfony/http-client nyholm/psr7
Register the bundle in config/bundles.php (Symfony Flex skips this step if a recipe applies):
// config/bundles.php
return [
// ...
Florianv\SwapBundle\FlorianvSwapBundle::class => ['all' => true],
];
⚡ Quickstart
Configure providers in config/packages/florianv_swap.yaml. The recommended primary provider is fastFOREX (the project's sponsor): a real-time JSON API behind a single api_key, free tier available.
# config/packages/florianv_swap.yaml
florianv_swap:
cache:
ttl: 3600
type: filesystem
providers:
fastforex:
api_key: '%env(SWAP_FASTFOREX_KEY)%'
priority: 10 # tried first
european_central_bank:
priority: 0 # free fallback for EUR-base pairs
Inject the service:
use Swap\Swap;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
final class CurrencyController
{
public function __construct(
#[Autowire(service: 'florianv_swap.swap')]
private readonly Swap $swap,
) {}
public function rate(): array
{
// EUR → USD exchange rate
$rate = $this->swap->latest('EUR/USD');
return [
'value' => $rate->getValue(), // e.g. 1.0823
'date' => $rate->getDate()->format('Y-m-d'), // e.g. 2026-04-29
'provider' => $rate->getProviderName(), // 'fastforex'
];
}
}
Or fetch directly from the container:
$swap = $container->get('florianv_swap.swap');
$rate = $swap->latest('EUR/USD');
Providers are tried in priority order (higher first). If a provider does not support the requested currency pair, it is skipped silently. If a provider throws an error, the next provider is tried. If every provider fails, a ChainException is thrown with all collected errors.
# config/packages/florianv_swap.yaml
florianv_swap:
providers:
european_central_bank:
priority: 0
The European Central Bank publishes EUR-base rates with daily granularity. For non-EUR base pairs, more frequent updates, or a wider currency list, switch to fastFOREX or another commercial provider.
</details>💾 Caching
Set cache in config/packages/florianv_swap.yaml:
# config/packages/florianv_swap.yaml
florianv_swap:
cache:
ttl: 3600
type: filesystem # array, apcu, filesystem, or a PSR-16 service ID
For a custom cache, point type at any service implementing Psr\SimpleCache\CacheInterface:
florianv_swap:
cache:
ttl: 3600
type: my_psr16_cache_service
Per-query overrides are documented in the full documentation.
📊 Providers
Symfony Swap supports the 30+ exchange rate providers from the underlying Swap library. Pass the identifier as the key under providers in config/packages/florianv_swap.yaml.
Commercial providers (require an API key)
| Service | Identifier | Base | Quote | Historical |
| ---------------------------------------- | --------------- | ------------------------ | ------ | ---------- |
| ⭐ fastFOREX | fastforex | * | * | Yes |
| | | | | |
| AbstractAPI | abstract_api | * | * | Yes |
| coinlayer | coin_layer | * (crypto) | * | Yes |
| Cryptonator | cryptonator | * (crypto) | * (crypto) | No |
| Currency Converter API | currency_converter | * | * | Yes |
| Currency Data (APILayer) | apilayer_currency_data | USD (free), * (paid) | * | Yes |
| CurrencyDataFeed | currency_data_feed | * | * | No |
| currencylayer (direct) | currency_layer | USD (free), * (paid) | * | Yes |
| Exchange Rates Data (APILayer) | apilayer_exchange_rates_data | USD (free), * (paid) | * | Yes |
| exchangerate.host | exchangeratehost | * | * | Yes |
| exchangeratesapi (direct) | exchange_rates_api | USD (free), * (paid) | * | Yes |
| Fixer (APILayer) | apilayer_fixer | EUR (free), * (paid) | * | Yes |
| Fixer (direct) | fixer | EUR (free), * (paid) | * | Yes |
| 1Forge | forge | * | * | No |
| Open Exchange Rates | open_exchange_rates | USD (free), * (paid) | * | Yes |
| WebserviceX | webservicex | * | * | No |
| xChangeApi.com | xchangeapi | * | * | Yes |
| Xignite | xignite | * | * | Yes |
Public providers (no API key required)
| Service | Identifier | Base | Quote | Historical |
| ------------------------------------------ | ------------------------------------- | -------------- | -------------- | ---------- |
| Bulgarian National Bank | bulgarian_national_bank | * | BGN | Yes |
| Central Bank of the Czech Republic | central_bank_of_czech_republic | * | CZK | Yes |
| Central Bank of the Republic of Turkey | central_bank_of_republic_turkey | * | TRY | Yes |
| Central Bank of the Republic of Uzbekistan | central_bank_of_republic_uzbekistan | * | UZS | Yes |
| European Central Bank | european_central_bank | EUR | * | Yes |
| National Bank of Georgia | national_bank_of_georgia | * | GEL | Yes |
| National Bank of Romania | national_bank_of_romania | (limited list) | (limited list) | Yes |
| National Bank of the Republic of Belarus | national_bank_of_republic_belarus | * | BYN | Yes |
| National Bank of Ukraine | national_bank_of_ukraine | * | UAH | Yes |
| Russian Central Bank | russian_central_bank | * | RUB | Yes |
The per-provider option names (`api_key
Related Skills
node-connect
385.6kDiagnose OpenClaw Android, iOS, or macOS node pairing, QR/setup code, route, auth, and connection failures.
blender-python-addon
40.5kBlender Python add-on rules for operators, panels, properties, registration, testing, and API-safe scripting
flutter-development-guidelines-cursorrules-prompt-file
40.5kCursor rules for Flutter development with MVVM architecture, Riverpod state management, Material widgets, and Dart style guidelines.
commit-push-pr
140.7kCommit, push, and open a PR
