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

AID: 8952
  • Status: Published

2820 points

  • Bymadaboutasp
  • TypeGeneral
  • Posted on2011-12-25 at 04:01:04
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
                                    
1:

Select allOpen 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=
                                    
1:

Select allOpen in new window



Lookup values (or stock symbols)

XCDUSD=X
                                    
1:

Select allOpen 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
                                    
1:

Select allOpen in new window



Result Format

&f=sl1d1t1
                                    
1:

Select allOpen 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;
}
?>
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:

Select allOpen 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;
}
?>
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:

Select allOpen 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;
} 
?>
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:

Select allOpen 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 = '' ); ?>
                                    
1:

Select allOpen 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' ); ?>
                                    
1:

Select allOpen 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' ); ?>
                                    
1:

Select allOpen 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' ); ?>
                                    
1:

Select allOpen 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>';
}?>
                                    
1:
2:
3:
4:

Select allOpen 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>';
}
?>
                                    
1:
2:
3:
4:
5:

Select allOpen in new window



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

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

Select allOpen in new window



Prints the currency name for USD from an array.

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

Select allOpen 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;
}
?>
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:

Select allOpen in new window

Asked On
2011-12-25 at 04:01:04ID8952
Tags

currency exchange

,

exhange rates

,

currency conversion

,

PHP

,

Yahoo! Finance

,

API

,

foreign exchange

,

php objects

Topic

PHP Scripting Language

Views
2153

Comments

Add your Comment

Please Sign up or Log in to comment on this article.

Join Experts Exchange Today

Gain Access to all our Tech Resources

Get personalized answers

Ask unlimited questions

Access Proven Solutions

Search 3.2 million solutions

Read In-Depth How-To Guides

1000+ articles, demos, & tips

Watch Step by Step Tutorials

Learn direct from top tech pros

And Much More!

Your complete tech resource

See Plans and Pricing

30-day free trial. Register in 60 seconds.

Loading Advertisement...

Top PHP Experts

  1. Ray_Paseur

    1,354,218

    Genius

    3,734 points yesterday

    Profile
    Rank: Savant
  2. DaveBaldwin

    284,951

    Guru

    4,300 points yesterday

    Profile
    Rank: Genius
  3. StingRaY

    144,754

    Master

    4,000 points yesterday

    Profile
    Rank: Wizard
  4. jason1178

    143,172

    Master

    1,000 points yesterday

    Profile
    Rank: Genius
  5. bportlock

    123,643

    Master

    1,600 points yesterday

    Profile
    Rank: Genius
  6. ChrisStanyon

    111,336

    Master

    0 points yesterday

    Profile
    Rank: Sage
  7. Roads_Roads

    106,350

    Master

    0 points yesterday

    Profile
    Rank: Genius
  8. maeltar

    95,247

    Master

    0 points yesterday

    Profile
    Rank: Guru
  9. gr8gonzo

    95,168

    Master

    0 points yesterday

    Profile
    Rank: Sage
  10. smadeira

    82,088

    Master

    0 points yesterday

    Profile
    Rank: Wizard
  11. Slick812

    77,062

    Master

    0 points yesterday

    Profile
    Rank: Sage
  12. johanntagle

    74,700

    Master

    2,000 points yesterday

    Profile
    Rank: Sage
  13. logudotcom

    67,088

    Master

    0 points yesterday

    Profile
    Rank: Genius
  14. COBOLdinosaur

    65,841

    Master

    0 points yesterday

    Profile
    Rank: Genius
  15. leakim971

    63,819

    Master

    0 points yesterday

    Profile
    Rank: Genius
  16. un1x86

    56,406

    Master

    0 points yesterday

    Profile
    Rank: Master
  17. Derokorian

    46,763

    10 points yesterday

    Profile
    Rank: Guru
  18. marqusG

    44,475

    10 points yesterday

    Profile
    Rank: Sage
  19. DrDamnit

    42,892

    0 points yesterday

    Profile
    Rank: Genius
  20. ahoffmann

    40,068

    0 points yesterday

    Profile
    Rank: Genius
  21. designatedinitializer

    37,800

    0 points yesterday

    Profile
    Rank: Master
  22. maestropsm

    37,678

    0 points yesterday

    Profile
    Rank: Guru
  23. TerryAtOpus

    34,800

    0 points yesterday

    Profile
    Rank: Genius
  24. xterm

    32,850

    0 points yesterday

    Profile
    Rank: Sage
  25. kaufmed

    31,808

    0 points yesterday

    Profile
    Rank: Genius

Hall Of Fame