dou91736 2018-06-05 03:13
浏览 291
已采纳

有没有更好的方法来获得PHP的货币汇率?

Currency Exchange Rate with below code is working sometimes and not working sometimes and not at all reliable. Is there any better way to get Currency Exchange Rate in PHP?

public function getJPYtoUSDExchangeRate(){
    $from    = 'JPY';
    $to    = 'USD';
    $amount  = 1;
    $data = file_get_contents("https://finance.google.com/finance/converter?a=$amount&from=$from&to=$to");
    preg_match("/<span class=bld>(.*)<\/span>/",$data, $converted);
    $converted = preg_replace("/[^0-9.]/", "", $converted[1][0]);
    return number_format(round($converted, 3),2);
}
  • 写回答

1条回答 默认 最新

  • dorpbn1027 2018-06-05 10:39
    关注

    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 be 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
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题