How to Implement Exchange Rate in PHP

Currency conversion formula

The rates in this XML are actually euro-rates: i.e., EUR/USD, EUR/JPY, etc. So what you need is:

$from = 'USD'; 
$to = 'JPY';
$amount = 100;

$conversion_rate = $rates[$from] / $rates[$to];
$converted_amount = round ($amount / $conversion_rate, 2);

Is there any better way to get Currency Exchange Rate in PHP?

You have several issues:

  • You're not calling an actual API, you're scraping a web page, which means that:
    • you're most likely violating Google's TOS
    • you're more likely to get rate-limited (or be detected as abuse and blacklisted) at some point if you're fetching this page too often
    • you're dependent on any change made in the HTML structure of the web page
  • You're scraping the page every single time you need to convert an amount to another currency, which means that any failure makes your currency conversion fail.

What you should do:

  • load exchange rates from a legitimate feed or API
  • load them on a regular basis (via a cron job for example) and save them to a local database, that will be used to perform currency conversions

This way, even if an API call fails, you still have access to a slightly outdated exchange rate, which is better than a failure in most cases.



Where do you find a trustable exchange rate feed?

There are plenty of APIs, free or not, that offer this service.

A good source I know of is the European Central Bank, who provides an XML feed that's been there for years and provides exchange rates for 32 currencies relative to EUR.

OpenExchangeRates also offers a free plan with a limit of 1,000 requests per month, which is enough to refresh rates every hour. It provides exchange rates for 170 currencies, relative to USD.

How do you store the values in your database?

Whichever feed you choose, you need to parse it (if XML) or json_decode() it (if JSON) and store the values in your database. Ideally, set up a cron job to run your import script daily or even hourly.

The actual parsing and importing steps are outside the scope of this question, but let's assume a simple MySQL table that holds the records:

CREATE TABLE exchange_rate(
target_currency CHAR(3) COLLATE ascii_bin NOT NULL PRIMARY KEY,
exchange_rate DOUBLE NOT NULL
);

How to properly handle currency conversions based on rates relative to a single currency?

This is a question I've answered recently. The feeds above give you rates to convert the base currency (EUR or USD) to another currency, but do not give you a clue on how to convert between two arbitrary currencies. I would suggest you use a proper library that handles these conversions for you, such as brick/money - disclaimer: I'm the author.

Here is how you would configure it to load your exchange rates from the table above:

use Brick\Money\CurrencyConverter;
use Brick\Money\ExchangeRateProvider\PDOProvider;
use Brick\Money\ExchangeRateProvider\PDOProviderConfiguration;
use Brick\Money\ExchangeRateProvider\BaseCurrencyProvider;

// set to whatever your rates are relative to
$baseCurrency = 'USD';

// use your own credentials, or re-use your existing PDO connection
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');

$configuration = new PDOProviderConfiguration();

$configuration->tableName = 'exchange_rate';
$configuration->exchangeRateColumnName = 'exchange_rate';
$configuration->targetCurrencyColumnName = 'target_currency';
$configuration->sourceCurrencyCode = $baseCurrency;

// this provider loads exchange rates from your database
$provider = new PDOProvider($pdo, $configuration);

// this provider calculates exchange rates relative to the base currency
$provider = new BaseCurrencyProvider($provider, $baseCurrency);

// this currency converter can now handle any currency pair
$converter = new CurrencyConverter($provider);

And how you would use it:

use Brick\Math\RoundingMode;
use Brick\Money\Money;

$money = Money::of(10, 'EUR'); // EUR 10.00
$converter->convert($money, 'CAD', RoundingMode::DOWN); // CAD 15.27

Update table dynamically with current currency conversion rates

Without knowing how much you can alter the page you are working with or what that page looks like, I'd like to suggest an alternative to fetching the exchange rates from an iframe.

This script works quite well.

<?php
function currency($from_Currency,$to_Currency,$amount) {
$amount = urlencode($amount);
$from_Currency = urlencode($from_Currency);
$to_Currency = urlencode($to_Currency);
$url = "http://www.google.com/ig/calculator?hl=en&q=$amount$from_Currency=?$to_Currency";
$ch = curl_init();
$timeout = 0;
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT , "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)");
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$rawdata = curl_exec($ch);
curl_close($ch);
$data = explode('"', $rawdata);
$data = explode(' ', $data['3']);
$var = $data['0'];
return round($var,3);
}

echo currency("GBP","USD",1);
?>

If this doesn't answer your problem, maybe it's of use to someone else.

Programmatically access currency exchange rates

You can get currency conversions in a simple format from yahoo:

For example, to convert from GBP to EUR:
http://download.finance.yahoo.com/d/quotes.csv?s=GBPEUR=X&f=sl1d1t1ba&e=.csv

How can I get foreign exchange rates thru an API by using PHP or Ajax?

I'll strongly recommend you CurrencyFreaks API. It provides foreign currency exchange rate endpoint in multiple languages including PHP and Ajax. It's prominent features are:

  • Data is updated every 60 sec.
  • You can change the ‘Base’ currency.
  • It provides currency exchange rates for 179 currencies worldwide including currencies, metals (Gold, Silver, Palladium, Platinum), and cryptocurrencies.
  • Supported codes for the endpoints are Shell, Node.js, Java, Python,
    PHP, Ruby, JS, C#, Go, C, Swift.

Here's the latest exchange rates endpoint using PHP:

setUrl('https://api.currencyfreaks.com/latest
?apikey=YOUR_APIKEY
&base=GBP
&symbols=EUR,USD,PKR,INR');
$request->setMethod(HTTP_Request2::METHOD_GET);
$request->setConfig(array(
'follow_redirects' => TRUE
));
try {
$response = $request->send();
if ($response->getStatus() == 200) {
echo $response->getBody();
}
else {
echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
$response->getReasonPhrase();
}
}
catch(HTTP_Request2_Exception $e) {
echo 'Error: ' . $e->getMessage();
}

For Ajax:

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function() {
if(this.readyState === 4) {
console.log(this.responseText);
}
});

xhr.open("GET", "https://api.currencyfreaks.com/latest
?apikey=YOUR_APIKEY
&base=GBP
&symbols=EUR,USD,PKR,INR");

xhr.send();

You can also get foreign exchange rate endpoint in other programming languages from here: https://currencyfreaks.com/documentation.html#Latest

I hope this solution will help for your recent project.

PHP: Apply exchange rate from a different table

Here's a solution that should work for your current table structure. However, I strongly suggest that you consider having one row per currency conversion in your fin_exchange_rates table. That way you could simply join on the appropriate row, instead of having all of the CASE statements.

Also, this solution assumes that the rates in your fin_exhange_rates table are relative to the PLN currency.

UPDATE fin_costs fc
JOIN fin_exchange_rates fer ON fc.year_analysis = fer.year_for_exchange
AND fc.month = fer.month_for_exchange
SET fc.gross_amount = (CASE
WHEN fc.currency = 'EUR' THEN fc.amount_in_currency * fer.EUR
WHEN fc.currency = 'USD' THEN fc.amount_in_currency * fer.USD
WHEN fc.currency = 'GBP' THEN fc.amount_in_currency * fer.GBP
WHEN fc.currency = 'PLN' THEN fc.amount_in_currency
END),
fc.net_amount = (CASE
WHEN fc.currency = 'EUR' THEN fc.amount_in_currency * fer.EUR
WHEN fc.currency = 'USD' THEN fc.amount_in_currency * fer.USD
WHEN fc.currency = 'GBP' THEN fc.amount_in_currency * fer.GBP
WHEN fc.currency = 'PLN' THEN fc.amount_in_currency
END)

Optionally add a WHERE clause to restrict to a certain month and/or year. Such as WHERE fc.month = 2 AND fc.year_analysis = 2013

SQLFiddle using slightly modified data

For completeness, here are the tables that I would use to replace your current fin_exchange_rates table…

CREATE TABLE `fin_currencies` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`abbreviation` varchar(16) NOT NULL,
`name` varchar(64) NOT NULL,
`displayCode` varchar(32) NOT NULL,
PRIMARY KEY (`id`);

CREATE TABLE `fin_exchange_rates` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`dateOfRate` date NOT NULL,
`fromCurrencyID` int(11) NOT NULL,
`toCurrencyID` int(11) NOT NULL,
`rate` decimal(14,8) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `date_from_to` (`dateOfRate`,`fromCurrencyID`,`toCurrencyID`);

The solution would then become something like this…

UPDATE fin_costs fc
JOIN fin_exchange_rates fer ON fc.year_analysis = YEAR(fer.dateOfRate)
AND fc.month = MONTH(fer.dateOfRate)
JOIN fin_currencies fcur1 ON fer.toCurrencyID = fcur1.id
AND fcur1.abbreviation = fc.currency
JOIN fin_currencies fcur2 ON fer.fromCurrencyID = fcur2.id
AND fcur2.abbreviation = 'PLN'
SET fc.gross_amount = fc.amount_in_currency * fer.rate,
fc.net_amount = fc.amount_in_currency * fer.rate

SQLFiddle for the preferred solution.

How to Convert Currency using google currency API in Php?

function thmx_currency_convert($amount){
$url = 'https://api.exchangerate-api.com/v4/latest/USD';
$json = file_get_contents($url);
$exp = json_decode($json);

$convert = $exp->rates->USD;

return $convert * $amount;
}
echo thmx_currency_convert(9);

Best way to use currency converter for faster result

First of all as a starting point do not try convert all the price every time. You just need a conversion rate so one api call per page load.
let's assume you are converting the price from USD to GNF (I am from Guinea) .
just convert from 1 USD -> ? GNF

$UsdToGnfRate=convertCurrency(1, 'USD', 'GNF')

from now on you can use this rate to convert all your product prices from USD to GNF by multipliying the product price by the rate you got from the api

foreach($products as $item){
$localPrice=$item['price'] * $UsdToGnfRate
}

You can make some test and see for your self or look for currency conversion which is based on the rate. This way you don't call the api for every product on your page.



Related Topics



Leave a reply



Submit