A PHP API Wrapper to offer a unified programming interface for popular Currency Rate APIs.
Dont worry about your favorite currency conversion service suddenly shutting down or switching plans on you. Switch away easily, without changing your code.
I needed a currency conversion API for my travel website but could not find a good PHP package. The idea of the
Rackbeat/php-currency-api
package came closest but unfortunately it
was just a stub and not implemented.
- Support for multiple different APIs through the use of drivers
- A fluent interface to make retrieving exchange rates convenient and fast
- Consistent return interface that is independent of the driver being used
- Calculations can be made based on the returned data
Service | Identifier |
---|---|
FixerIO | fixerio |
CurrencyLayer | currencylayer |
Open Exchange Rates | openexchangerates |
Exchange Rates API | exchangeratesapi |
If you want to see more services added, feel free to open an issue!
PHP 8.x
orPHP 7.3+
or higher (tested on both7.3
and7.4
)- The
composer
dependency manager for PHP - An account with one or more of the API providers listed above
Simply require the package using composer
and you're good to go!
$ composer require otherguy/php-currency-api
The Otherguy\Currency\Symbol
class provides constants for each supported currency.
!Note: You are not required to use
Otherguy\Currency\Symbol
to specify symbols. It's simply a convenience helper and does not need to be used. You can simply pass strings like'USD', 'EUR', ...
to all methods.
// 'USD'
$symbol = Otherguy\Currency\Symbol::USD;
Use the all()
method to retrieve an array of all currency symbols:
// [ 'AED', 'AFN', ... 'ZWL' ]
$symbols = Otherguy\Currency\Symbol::all();
The names()
method returns an associative array with currency names instead:
// [ 'AED' => 'United Arab Emirates Dirham', 'AFN' => 'Afghan Afghani', ... ]
$symbols = Otherguy\Currency\Symbol::names();
To get the name of a single currency, use the name()
method:
// 'United States Dollar'
$symbols = Otherguy\Currency\Symbol::name(Otherguy\Currency\Symbol::USD);
$currency = Otherguy\Currency\DriverFactory::make('fixerio'); // driver identifier from supported drivers.
To get a list of supported drivers, use the getDrivers()
method:
// [ 'mock', 'fixerio', 'currencylayer', ... ]
$drivers = Otherguy\Currency\DriverFactory::getDrivers()
Most API providers require you to sign up and use your issued access key to authenticate against their API. You can specify your access key like so:
$currency->accessKey('your-access-token-goes-here');
To set further configuration options, you can use the config()
method. An example is
CurrencyLayer's JSON formatting option.
$currency->config('format', '1');
You can use either from()
or source()
to set the base currency. The methods are identical.
!Note: Each driver sets its own default base currency. FixerIO uses
EUR
as base currency while CurrencyLayer usesUSD
.
Most services only allow you to change the base currency in their paid plans. The driver will throw a
Otherguy\Currency\Exceptions\ApiException
if your current plan does not allow changing the base currency.
$currency->source(Otherguy\Currency\Symbol::USD);
$currency->from(Otherguy\Currency\Symbol::USD);
You can use either to()
or symbols()
to set the return currencies. The methods are identical. Pass a single currency
or an array of currency symbols to either of these methods.
!Note: Pass an empty array to return all currency symbols supported by this driver. This is the default if you don't call the method at all.
$currency->to(Otherguy\Currency\Symbol::BTC);
$currency->symbols([Otherguy\Currency\Symbol::BTC, Otherguy\Currency\Symbol::EUR, Otherguy\Currency\Symbol::USD]);
This retrieves the most recent exchange rates and returns a ConversionResult
object.
$currency->get(); // Get latest rates for selected symbols, using set base currency
$currency->get('DKK'); // Get latest rates for selected symbols, using DKK as base currency
To retrieve historical exchange rates, use the historical()
method. Note that you need to specify a date either as a
method parameter or by using the date()
methods. See Fluent Interface for more information.
$currency->date('2010-01-01')->historical();
$currency->historical('2018-07-01');
Use the convert()
method to convert amounts between currencies.
!Note: Most API providers don't allow access to this method using your free account. You can still use the Latest Rates or Historical Rates endpoints and perform calculations or conversions on the
ConversionResult
object.
$currency->convert(10.00, 'USD', 'THB'); // Convert 10 USD to THB
$currency->convert(122.50, 'NPR', 'EUR', '2019-01-01'); // Convert 122.50 NPR to EUR using the rates from January 1st, 2019
Most methods can be used with a fluent interface, allowing you to chain method calls for more readable code:
// Namespaces are omitted for readability!
DriverFactory::make('driver')->from(Symbol::USD)->to(Symbol::EUR)->get();
DriverFactory::make('driver')->from(Symbol::USD)->to(Symbol::NPR)->date('2013-03-02')->historical();
DriverFactory::make('driver')->from(Symbol::USD)->to(Symbol::NPR)->amount(12.10)->convert();
The get()
and historical()
endpoints return a
ConversionResult
object. This object allows you to perform calculations and
conversions easily.
!Note: Even though free accounts of most providers do not allow you to change the base currency, you can still use the
ConversionResult
object to change the base currency later. This might not be as accurate as changing the base currency directly, though.
!Note: To convert between two currencies, you need to request both of them in your initial
get()
orhistorical()
request. You can not convert between currencies that have not been fetched!
See the following code for some examples of what you can do with the ConversionResult
object.
$result = DriverFactory::make('driver')->from(Symbol::USD)->to([Symbol::EUR, Symbol::GBP])->get();
// [ 'USD' => 1.00, 'EUR' => 0.89, 'GBP' => 0.79 ]
$result->all();
// 'USD'
$result->getBaseCurrency();
// '2019-06-11'
$result->getDate();
// 0.89
$result->rate(Symbol::EUR);
// CurrencyException("No conversion result for BTC!");
$result->rate(Symbol::BTC);
// 5.618
$result->convert(5.0, Symbol::EUR, Symbol::USD);
// [ 'USD' => 1.13, 'EUR' => 1.00, 'GBP' => 0.89 ]
$result->setBaseCurrency(Symbol::EUR)->all();
// 1.12
$result->setBaseCurrency(Symbol::GBP)->rate(Symbol::EUR);
Pull Requests are more than welcome! I'm striving for 100% test coverage for this repository so please make sure to add tests for your code.