Currency conversion in PHP

Posted on Friday, December 19th, 2008 under , ,

I was looking for a way to include a currency converter in a website. Not wanting to reinvent the wheel, I googled around for a PHP currency conversion tool, but I didn’t find anything suitable. They were bloated, filled with annoying copyright notices with lots of logos or you had to include a file from their server. In other words, only crap. I needed something simple. You know…get in, score, get out.

Exchange Rate function

So I’ve wrote a small PHP function, that queries Google for the current exchange rate. It works okay and it’s reasonably fast, depending on the server’s bandwidth. Of course, I’m talking about the server on with the script runs, not Google’s servers, because those are fast enough to fulfill every porn addict’s wildest dreams.

The function is quite easy to use, as you can see in the following example:

require( '/path/to/exchange_rate.php' );
echo '100 euro equals ' . exchangeRate( 100, 'euro', 'usd' ) . ' US Dollars and ' . exchangeRate( 100, 'euro', 'canadian dollars' ) . ' Canadian Dollars';

The first parameter is the amount, the second one is the currency in which the amount is expressed in, and the third one is the currency in which you want to make the exchange. Since Google’s algorithms are very reliable, currencies’ names can be expressed in many ways. For example, the function will work with any of “usd”, “us dollars”, “united states dollars”, and so on. If the query fails, the function will simply return false.

Source code and disclaimer

Here it is:

/**
 * queries Google for the current exchange rate, doesn't need cURL
 * 
 * @param mixed  $amount
 * @param string $currency
 * @param string $exchangeIn
 * @return mixed
 * @author Tudor Barbu
 * @copyright MIT 
 */
function exchangeRate( $amount, $currency, $exchangeIn )
{
    $googleQuery = $amount . ' ' . $currency . ' in ' . $exchangeIn;
    $googleQuery = urlEncode( $googleQuery );
    $askGoogle = file_get_contents( 'http://www.google.com/search?q=' . $googleQuery );
    $askGoogle = strip_tags( $askGoogle );
    $matches = array();
    preg_match( '/= (([0-9]|\.|,|\ )*)/', $askGoogle, $matches );
    return $matches[1] ? $matches[1] : false;
}
 
echo exchangeRate( 1000, 'euro', 'dollars' );

But keep in mind that if Google changes the way currency conversion queries are displayed, this function might not work properly, or, depending on your luck, might not work at all. Also, it would be best if you’d read Google’s Currency Conversion Disclaimer before using this function.

Later edit

See this comment for an improved version of the script made by the user Manic.
Even later edit: check out this script: Better PHP Exchange rate. It’s much better :P

Related posts

50 Responses to “Currency conversion in PHP”

Trackbacks (2)

Comments (48)

  1. • Iuri •

    Nice code mate!
    Does it work with australian dollars as well?

  2. Mihai

    Yes, I admire your “do it your way” style, and thanks for sharing. What your professional blog needs (and what I’ve seen on other technical blogs) is a deploy page for the examples, or an embedded area within the post, for dummies to see the exact result and the implementation.

  3. Tudor

    Iuri: it works with any currency supported by Google’s conversion engine.
    Mihai: almost every post has a downloadable example. Just take it, unzip it and run it on your machine.

  4. • Mattew Morris •

    Hi, any idea if there’s a way to force Google to return values to the nearest whole number? I’ve tried to use PHP’s “round” function, but it can’t deal with the commas that google returns to seperate thousands up. Thanks!

  5. • Mattew Morris •

    Sorry, correction – Google returns a space after the thousand. “1300″ returns as “1 300″

  6. • Mattew Morris •

    For anyone who’s interested – I solved my problem above by using the following:

    It replaces the space that Google returns after the “thousand” and then rounds down to the nearest whole number.

  7. Tudor

    I’m glad you’ve find it usefull. Thank you for your positive feedback.

  8. • Mattew Morris •

    Hmm, the example above didn’t paste properly….

    echo round(str_replace (” “,””,(exchangeRate( 1000, ‘gbp’, ‘usd’ ))));

  9. • Manic •

    Nice one, I used this to loop through a bunch of currency codes and get rates. I found that the function, in some cases, returns a value that is not a currency conversion.

    To solve this you need to add a pregmatch that checks to see if the resulting page is infact a conversion result page and not a standard google search result list.

    function exchangeRate( $amount, $currency, $exchangeIn )
    {
    	$googleQuery = $amount . ' ' . $currency . ' in ' . $exchangeIn;
    	$googleQuery = urlEncode( $googleQuery );
    	$askGoogle = file_get_contents( 'http://www.google.com/search?q=' . $googleQuery );
    	$askGoogle = strip_tags( $askGoogle );
    	if (preg_match("/Rates provided for information only - see disclaimer./i", $askGoogle)) {
    		$matches = array();
    		preg_match( '/= (([0-9]|.|,| )*)/', $askGoogle, $matches );
    		return $matches[1] ? $matches[1] : false;
    	}
    	else {
    		$status = 'google says no';
    		return $status;
    	}
    }
  10. Tudor

    Well done Manic, thank you! I’ve edited this post and added a link to your comment!

  11. Tudor

    Offedwimi> say what?

  12. • Naga sunford •

    hello
    is any body to know the conversion of code in php from usd to Euro.becaZ im a php learner and beginner. so any body could help me

    FYI

    i have two text box 1 for dollar and another for euro .
    if type the value of us dollar in a text then click convert button it will automatically changed in Euro value in the another text box

  13. Tudor

    Have you tried AJAX?

  14. • Seb •

    I have used the script but it returns the whole string after “= “.

    So I have modified the regular expression into:

    /= ([0-9\s\.,]+)/

    so that the preg_match becomes:

    preg_match( ‘/= ([0-9\s\.,]+)/’, $askGoogle, $matches );

    I am not an expert in regular expressions I tried to make it work with any digit, the white space, the “.” and the “,”.

    However, if you put large amounts google will return, for example, the word “million” and divide the result by one million, so this means that the function needs to be further “cleaned”.

    if you enter:

    1000000 gbp in usd

    Google returns:

    1 000 000 British pounds = 1.9866 million U.S. dollars

    any idea?

  15. • jaswant •

    where is the script to download. Downlod link is not working.

  16. NS

    I also got an error why I tried downloading the file. Can you correct this?

    Thanks.

  17. Tudor

    Problem fixed, both of you!

  18. Tudor

    Yes, but I still have to parse the result with regular expressions. I want the converted value in one of my scripts…

  19. Radu

    In the end I used BNR’s official currency data (it’s only for RON):
    http://www.bnro.ro/nbrfxrates.xml

  20. Tudor

    Yes, but this feed is quite recent. It’s only 2 or 3 weeks old :P At the time this article was written, the National Bank of Romania had a page that looked like it was developed in MS word or something similar and no XML feeds…

    Anyway, nice find :P

  21. • Jrok •

    Hey I’m having the same issue with removing the space when the ‘price’ is in the thousands, AND rounding it out to two decimal places. This is SO perfect for what I’m trying to do, but dang, not close enough!

    $unitprice = 1399.99; //sample, is actually pulled from a DB
    function exchangeRate( $amount, $currency, $exchangeIn )
    {
        $googleQuery = $amount . ' ' . $currency . ' in ' . $exchangeIn;
        $googleQuery = urlEncode( $googleQuery );
        $askGoogle = file_get_contents( 'http://www.google.com/search?q=' . $googleQuery );
        $askGoogle = strip_tags( $askGoogle );
        $matches = array();
        preg_match( '/= (([0-9\s]|\.|,|\ )*)/', $askGoogle, $matches ); //removes the space for actual conversion process...
        return $matches[1] ? $matches[1] : false;
    }
     
    //exchangeRate( $unitprice, "cad", "usd");
     
    $roundIt = exchangeRate( $unitprice, "cad", "usd"); 
    $usVal = str_replace(" ","",$roundIt);
    $newUsVal = number_format($usVal,2,".",",");
     
    if ($roundIt > 0 )
    	echo "$" . str_replace(" ", "",$usVal) . " USD";

    I’ve tried str_replace with  , and with %20; and I’m at a loss — please help!

  22. Tudor

    Get the exchange rate for a single monetary unit and compute the price at your end:

    $unit_price = 1399.99;
    $exchange_rate = exchangeRate( 1, 'cad', 'usd' );
    $exchanged_price = $unit_price * $exchange_rate;
  23. • Jrok •

    GAH…. sometimes my brain gets stuck in a ‘rut’ of how to go about these things — thank you.

  24. Tudor

    Lol, I hear you! It happens a lot to me too…

  25. Emmanuel

    Hey, it seems to work perfect, but it is displaying 5 decimals. Is there any way that I can make it display only 2?

  26. Emmanuel

    Nevermind, I just figured out, but thank you so much anyways. It works amazingly perfect

  27. • Mike VandeVelde •

    Hi, this looks like it would work great, except that Google returns something like:

    403 ForbiddenGoogle Error ForbiddenYour client does not have permission to get URL /search?q=1+cad+in+eur from this server. (Client IP address: x.x.x.x) Please see Google’s Terms of Service posted at http://www.google.com/terms_of_service.html If you believe that you have received this response in error, please report your problem blah blah blah

    I guess they don’t like you hitting their search with a script? Have you ever seen this issue? Is this something they just started doing recently?

    Thanks for posting this anyway, but oh well back to the drawing board I guess…

  28. Tudor

    I’ve ran the script again, this morning and it works…Could there be a problem at your end? Try it on a different IP…

  29. • laforge •

    Very handy script. Thanks for this.

  30. Martin Walker

    This is great!! Thanks.

    I just implemented the code to translate a fixed Euro product price into Danish krona, rounding to the nearest kr. Works beautifully. And so much simpler than anything else out there. Well done.

    Here’s the page: http://www.mindsparke.dk/buy.php

    Martin

  31. Tudor

    I’ve looked over your site. You should really add a shareware version of the software on the site.

  32. Martin Walker

    Hi Tudor.

    What makes you say that? I’m curious.

    Martin

  33. Tudor

    Well, people might want to try it out before buying it. And while that might seem a bargain where you live, for some of us it isn’t.

    And when an offer is too good…well…it usually isn’t. I’m sure that I’m not the only one who would like to try it out before acquiring it.

  34. Martin Walker

    Ah, I see. Thanks, Tudor.

    The program presents an unusual problem in this regard. It requires a good deal of commitment and effort on the part of the user before he or she would be able to say whether it worked for them or not. The user must train for no less than ten days before the results begin to appear. This is because it is stimulating changes in working memory and focus. The training is also particularly difficult for the first few days.

    This means that someone who purchases the software to perform the usual product evaluation (how does it look, what will it do for me) will find themselves immediately faced with the need to commit. (Reviewers have agreed with the conclusion that a trial version would be a bad idea.)

    Instead I offer the full, unconditional money-back guarantee, plus an additional $40 if someone commits to ten days and doesn’t find it useful. (I’ve had a few returns, but no one has yet taken me up on that ten day offer!!)

    If anyone contacts me wanting to try the software, I am always more than willing to supply a copy.

    Martin

  35. Lars Sorhus

    Hi Guys,

    Here’s a much easier way:

    http://www.google.com/ig/calculator?hl=en&q=2.5AUD=?GBP

    It does output it as JSON, but it’s consistent and easilly parsable.

    Cheers,

    Lars

  36. Tudor

    It wasn’t when this post was originally written, but it’s a much better way indeed. Great find Lars :P

  37. Tudor

    PS: another version of the script is available here.

  38. • sohail •

    Plz tell me step by step how to use this script. I need to insert it in my html webpage.. please help..

  39. Tudor

    Doesn’t work with HTML! You need PHP on the server…

  40. • sohail •

    I hve PHP in my server.. I meant to say.. I need to embed this code in html page…

  41. • sohail •

    Plz tell me step by step procedure how to use this script. I need to insert it in my html webpage.. please help . I hve PHP in my server.

  42. Tudor

    Learn your PHP stuff! This blog is not for the absolute beginners. Basically all you have to do is call the exchangeRate function…

  43. • sohail •

    I am not webmaster or sum thing. I am going to be professional in web related stuffs, but this is really urgent for me. I want to insert this converter in my non profit website. Please help.

  44. • Suresh •

    Thanks man for this code. it helped me a lot… :)

  45. • 1337ingDisorder •

    Hi Tudor,

    This script has been working great for months but it seems to have broken today, I suspect Google may have changed the format of their output or something to that effect.

    The error output it’s now giving is as follows:

    PHP Notice: Undefined offset: 1 in /path/to/currency_converter.php on line 21

    This happened with the usual cron-triggered execution at 8:30am this morning and is still happening when I try manually now (it’s now around noon).

    Will try again later in case it’s just a Google hiccup but you may want to try yourself to see if you get the same results or whether it’s just busted for my deployment. :)

    Thanks again for writing this script in the first place, has kept my bosses happy for a long time so far!

    – 1337ingDisorder

  46. • 1337ingDisorder •

    Cancel my last post, the currency conversion is actually working fine. Our problem is that a different script (based on Apple reports, which have changed their format) started passing bad variables to the currency converter.

    Sorry for the false alarm and thanks again for this handy script! :)

    – 1337ingDisorder

Leave a Reply