<

Getting Currency Exchange Rates with PHP and Yahoo! Finance CSV API

Published on
32,805 Points
26,605 Views
2 Endorsements
Last Modified:
Approved
I imagine that there are some, like me, who require a way of getting currency exchange rates for implementation in web project from time to time, so I thought I would share a solution that I have developed for this purpose.

It turns out that Yahoo! Finance has a CSV API that makes it very easy to get currency exchange rates (and stock quotes) in CSV format by using a URL like this one (and it’s FREE!):

http://finance.yahoo.com/d/quotes.csv?s=XCDUSD=X&f=sl1d1t1

Open in new window


This will tell us the last conversion rate for Eastern Caribbean Dollars (XCD) to United States Dollars (USD). At this point it would be useful to learn about currency codes.

Breaking down the URL

To begin, let’s try to understand the Yahoo! Finance URL.

URL Start

http://finance.yahoo.com/d/quotes.csv?s=

Open in new window


Lookup values (or stock symbols)

XCDUSD=X

Open in new window


The first three letters here indicate the currency you are converting from, the next three indicate the currency you are converting to, and ‘=X’ presumably says you are querying an exchange rate. That said, if you want to query multiple rates you could enter comma separated values like this:

XCDUSD=X,XCDGBP=X,XCDEUR=X

Open in new window


Result Format

&f=sl1d1t1

Open in new window


This part suggests the format or the fields that should be returned in the data. Let’s describe each part in turn.

s       =       the Symbol (lookup value) queried.
l1      =       the last exchange value
d1      =       the last exchange date
t1       =       the last exchange time

Up to this point you should be able to download a CSV file with the data you desire, and use it that way in some solutions. But here our objective is to demonstrate how to read that data using PHP and return it as an array or a standard class objects.

Building the PHP Solution

Our objective is to develop a solution that would offer the following options:
1.      Lookup or query multiple currencies
2.      Convert a single ‘base’ currency to multiple ‘targets’ or convert those ‘targets’ to the ‘base’ currency.
3.      Output the results as either an associative array or a standard class object.

We will use PHP file handling techniques to get data from the CSV file rather than downloading it. At this point I should explain that each line of data would be returned as an array with numerical keys. So the first step in building the solution is to find a way of exchanging the numerical keys with something more useful.

Adding Useful Array Keys

To address this issue we will first create a way to change the numeric keys to some useful values. This helps us crate our associative array later on, and it also makes more sense if we convert the results to a standard class object.

<?php
/*
* @function: add_cx_keys( $array )
*/
function add_cx_keys( $array ) {
	/*
	* @keys: Define the desired array keys in an array
	*/
	$target_keys = array( 'cx_name', 'cx_code', 'cx_test', 'cx_rate', 'cx_date', 'cx_time' );
	$i = 0;
	foreach($target_keys as $key) {
		$arrOutput[$key] = $array[$i];
		$i++;
	}
	return $arrOutput;
}
?>

Open in new window


Converting Arrays to Objects

To be able to make our results into an object later on, we would need a technique to convert arrays to objects. This pair of functions would do that very nicely.

<?php
/*
* @function: make_array_object() | array_to_object() - convert an associative array to an object
*/
function make_array_object( $array ) {
	$object = new stdClass();
	return array_to_object( $array, $object );
}

function array_to_object( $arr, &$obj ) {
	foreach( $arr as $key=>$val )
	{
		if( is_array( $val ) )
		{
			$obj->$key = new stdClass();
			array_to_object( $val, $obj->$key );
		}
		else
		{
			$obj->$key = $val;
		}
	}
	return $obj;
}
?>

Open in new window


Getting those Exchange Rates

The functions defined so far, would play supporting roles in the overall solution. We now turn to the function that really puts this solution into gear, and delivers our desired results.

<?php
function get_exchange_rates( $home_currency, $convert_to = '', $additional_targets = array(), $output_type = '' ) {
	/*
	* @default_targets: A list of default (popular|moset used) currencies
	*/
	$default_targets = array( 
		'USD'=>'US Dollar',
		'EUR'=>'Euro',
		'GBP'=>'British Pound',
		'AUD'=>'Australian Dollar',
		'CAD'=>'Canadian Dollar',
		'CHF'=>'Swiss Franc',
		'INR'=>'India Rupee',
		'CNY'=>'Chinese Yuan Renminbi',
		'NZD'=>'New Zealand Dollar',
		'JPY'=>'Japan Yen',
		'BBD'=>'Barbados Dollar',
		'BSD'=>'Bahamas Dollar',
		'BZD'=>'Belize Dollar',
		'GYD'=>'Guyana Dollar',
		'JMD'=>'Jamaica Dollar',
		'TTD'=>'Trinidad and Tobago Dollar',
		'XCD'=>'Eastern Caribbean Dollar'
	);
	
	/*
	* @additional_targets: Add more currencies if available
	*/
	if( !empty( $additional_targets ) && is_array( $additional_targets ) ) {
		$target_currencies = array_merge( $default_targets, $additional_targets );
	} else {
		$target_currencies = $default_targets;
	}
	
	/*
	* @unset: Remove home currency from targets
	*/
	if( array_key_exists( $home_currency, $target_currencies ) ) {
		unset( $target_currencies[$home_currency] );
	}
	
	/*
	* @loop: Loop through the targets and perform lookup on Yahoo! Finance
	*/
	foreach( $target_currencies as $code => $name ) {
		/*
		* @url: Get the URL for csv file at Yahoo API, based on 'convert_to' option
		*/
		switch( strtoupper( $convert_to ) ) {
			case 'H': /* Converts targest to home */
				$url = sprintf( "http://finance.yahoo.com/d/quotes.csv?s=%s%s=X&f=sl1d1t1", $code, $home_currency );
			break;
			case 'T': /* Converts home to targets */
			default:
				$url = sprintf( "http://finance.yahoo.com/d/quotes.csv?s=%s%s=X&f=sl1d1t1", $home_currency, $code );
			break;
		}
		
		/*
		* @fopen: open and read API files
		*/
		$handle = @fopen( $url, 'r' );
		if ( $handle ) {
			$result = fgets( $handle, 4096 );
			fclose( $handle );
		}
		
		/*
		* @output: Create output array and add currency code and descriptive (Country) name
		*/
		$arrOutput[$code] = explode( ',', $result );
		array_unshift( $arrOutput[$code], $code ); /* Add the code */
		array_unshift( $arrOutput[$code], $name ); /* Add the name */
		
		/*
		* @keys: Substitute numerical keys with user friendly ones
		*/
		$arrOutput[$code] = add_cx_keys( $arrOutput[$code] );
	}
	
	/*
	* @object: Convert array to object if required
	*/
	if( strtoupper( $output_type ) == 'OBJECT' ) {
		$arrOutput = make_array_object( $arrOutput );
	}
	
	/*
	* @return: Return the output array or object
	*/
	return $arrOutput;
} 
?>

Open in new window


You would notice that I done considerable commenting within the code for this function. Those comments should pretty much explain what it does, and how. Just put this function together with the others, stick them into your web project and you have the complete setup to grab those exchange rates.

Now let us look at a typical implementation and the parameters we can pass to our function.

<?php $rates = get_exchange_rates( $home_currency, $convert_to = '', $additional_targets = array(), $output_type = '' ); ?>

Open in new window

 

The function takes four (4) parameters, which are detailed as follows:

$home_currency
(string) (required) . The currency code of your choice, and for which you wish to get exchange rates.
Default: None

$convert_to
(string) (optional). Determines whether to perform conversion to Home Currency (H) or Target Currencies (T). You can also pass ‘null’ to this parameter if you want to access $additional_targets.
Options: ‘H’, ‘T’
Default: ‘T’.

$additional_targets
(array) (optional). Add additional target currencies if desired. You can also pass ‘null’ to this parameter if you want to access $output_type.
Default:  array()

$output_type
(string) (optional). This determines whether to output associative array or standard class object.
Options: ‘ARRAY_A’, ‘OBJECT’
Default: ‘ARRAY_A’

Examples of Use

<?php $rates = get_exchange_rates( ‘XCD' ); ?>

Open in new window


Returns the rates for Eastern Caribbean Dollars in the default list, as an associative array.

<?php $rates = get_exchange_rates( ‘XCD', ‘H' ); ?>

Open in new window


Returns the rates in Eastern Caribbean Dollars for each of the currencies in the default list.

<?php $rates = get_exchange_rates( ‘XCD', null, array( ‘EGP'=>'Egypt Pound' ), ‘OBJECT' ); ?>

Open in new window


Returns the rates for Eastern Caribbean Dollars in the default currencies and Egypt Pounds as an object.

<?php
foreach( $rates as $rate ) {
	echo '<p>' . $rate['cx_name'] . ' ('. $rate['cx_rate'] . ')</p>';
}?>

Open in new window


Prints the name and rate for each target currency from an array.

<?php
foreach( $rates as $rate ) {
	echo '<p>' . $rate->cx_name . '('. $rate->cx_rate . ')</p>';
}
?>

Open in new window


Prints the name and rate for each target currency from an object.

<?php echo $rates['USD']['cx_name']; ?>

Open in new window


Prints the currency name for USD from an array.

<?php echo $rates->EUR->cx_name; ?>

Open in new window



Prints the currency name for EUR from an object.


Putting it all Together

For convenience, let’s put the complete code for this solution together.  For your convenience or preference you might adjust the values of the default_targets array. And there you go! I hope you find this useful for your projects, and have fun getting those exchange rates.

<?php
/*
* @function: get_echange_rates() - get currency echanges rates using Yahoo! Finance CSV API
*/
function get_exchange_rates( $home_currency, $convert_to = '', $additional_targets = array(), $output_type = '' ) {
	/*
	* @default_targets: A list of default (popular|moset used) currencies
	*/
	$default_targets = array( 
		'USD'=>'US Dollar',
		'EUR'=>'Euro',
		'GBP'=>'British Pound',
		'AUD'=>'Australian Dollar',
		'CAD'=>'Canadian Dollar',
		'CHF'=>'Swiss Franc',
		'INR'=>'India Rupee',
		'CNY'=>'Chinese Yuan Renminbi',
		'NZD'=>'New Zealand Dollar',
		'JPY'=>'Japan Yen',
		'BBD'=>'Barbados Dollar',
		'BSD'=>'Bahamas Dollar',
		'BZD'=>'Belize Dollar',
		'GYD'=>'Guyana Dollar',
		'JMD'=>'Jamaica Dollar',
		'TTD'=>'Trinidad and Tobago Dollar',
		'XCD'=>'Eastern Caribbean Dollar'
	);
	
	/*
	* @additional_targets: Add more currencies if available
	*/
	if( !empty( $additional_targets ) && is_array( $additional_targets ) ) {
		$target_currencies = array_merge( $default_targets, $additional_targets );
	} else {
		$target_currencies = $default_targets;
	}
	
	/*
	* @unset: Remove home currency from targets
	*/
	if( array_key_exists( $home_currency, $target_currencies ) ) {
		unset( $target_currencies[$home_currency] );
	}
	
	/*
	* @loop: Loop through the targets and perform lookup on Yahoo! Finance
	*/
	foreach( $target_currencies as $code => $name ) {
		/*
		* @url: Get the URL for csv file at Yahoo API, based on 'convert_to' option
		*/
		switch( strtoupper( $convert_to ) ) {
			case 'H': /* Converts targest to home */
				$url = sprintf( "http://finance.yahoo.com/d/quotes.csv?s=%s%s=X&f=sl1d1t1", $code, $home_currency );
			break;
			case 'T': /* Converts home to targets */
			default:
				$url = sprintf( "http://finance.yahoo.com/d/quotes.csv?s=%s%s=X&f=sl1d1t1", $home_currency, $code );
			break;
		}
		
		/*
		* @fopen: open and read API files
		*/
		$handle = @fopen( $url, 'r' );
		if ( $handle ) {
			$result = fgets( $handle, 4096 );
			fclose( $handle );
		}
		
		/*
		* @output: Create output array and add currency code and descriptive (Country) name
		*/
		$arrOutput[$code] = explode( ',', $result );
		array_unshift( $arrOutput[$code], $code ); /* Add the code */
		array_unshift( $arrOutput[$code], $name ); /* Add the name */
		
		/*
		* @keys: Substitute numerical keys with user friendly ones
		*/
		$arrOutput[$code] = add_cx_keys( $arrOutput[$code] );
	}
	
	/*
	* @object: Convert array to object if required
	*/
	if( strtoupper( $output_type ) == 'OBJECT' ) {
		$arrOutput = make_array_object( $arrOutput );
	}
	
	/*
	* @return: Return the output array or object
	*/
	return $arrOutput;
}

/*
* @function: make_array_object() | array_to_object() - convert an associative array to an object
*/
function make_array_object( $array ) {
	$object = new stdClass();
	return array_to_object( $array, $object );
}

function array_to_object( $arr, &$obj ) {
	foreach( $arr as $key=>$val )
	{
		if( is_array( $val ) )
		{
			$obj->$key = new stdClass();
			array_to_object( $val, $obj->$key );
		}
		else
		{
			$obj->$key = $val;
		}
	}
	return $obj;
}

/*
* @function: add_cx_keys( $array )
*/
function add_cx_keys( $array ) {
	$target_keys = array( 'cx_name', 'cx_code', 'cx_test', 'cx_rate', 'cx_date', 'cx_time' );
	$i = 0;
	foreach($target_keys as $key) {
		$arrOutput[$key] = $array[$i];
		$i++;
	}
	return $arrOutput;
}
?>

Open in new window

2
Author:Ovid Burke
Ask questions about what you read
If you have a question about something within an article, you can receive help directly from the article author. Experts Exchange article authors are available to answer questions and further the discussion.
Get 7 days free