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

时间:2018-06-05 03:13:31

标签: php currency

使用以下代码的货币兑换率有时会起作用,有时不起作用,而且根本不可靠。有没有更好的方法来获得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);
}

3 个答案:

答案 0 :(得分:2)

您有几个问题:

  • 您没有调用实际的API,而是在抓取网页,这意味着:
    • 您最有可能违反Google的服务条款
    • 如果您过于频繁地抓取此页面,则您更有可能在某些时候获得速率限制(或被检测为滥用并被列入黑名单)
    • 您依赖于网页HTML结构中所做的任何更改
  • 您每次需要将金额转换为其他货币时都会抓取页面,这意味着任何失败都会导致您的货币转换失败。

你应该做什么:

  • 从合法Feed或API加载汇率
  • 定期加载(例如通过cron作业)并将其保存到本地数据库,这将用于执行货币转换

这样,即使API调用失败,您仍然可以访问稍微过时的汇率,这比大多数情况下的失败要好。

您在哪里可以找到可靠的汇率?

有许多API,无论是否免费提供此服务。

我所知道的一个很好的来源是欧洲中央银行,它提供XML feed多年来一直在那里,提供相对于EUR的32种货币的汇率。

OpenExchangeRates还提供免费计划,每月限制为1,000个请求,足以每小时刷新一次。它提供170种货币的汇率,相对于USD

如何在数据库中存储值?

无论您选择哪种Feed,都需要解析它(如果是XML)或json_decode()它(如果是JSON)并将值存储在数据库中。理想情况下,设置一个cron作业来每天甚至每小时运行一次导入脚本。

实际的解析和导入步骤超出了本问题的范围,但我们假设一个简单的MySQL表保存记录:

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

如何根据相对于单一货币的汇率正确处理货币转换?

这是一个我answered recently的问题。上面的Feed为您提供了将基础货币(EURUSD)转换为其他货币的费率,但不会为您提供如何在两种任意货币之间进行转换的线索。我建议您使用适当的库来处理这些转换,例如brick/money - 免责声明:我是作者

以下是如何将其配置为从上表中加载汇率:

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);

以及如何使用它:

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

答案 1 :(得分:2)

CurrencyFreaks API以兼容多种编程语言的JSON和XML格式提供了全球179种货币的可信赖汇率。通过使用CurrencyFreaks API,您还可以更改“基本”货币并获得特定货币的汇率。

以下是使用PHP的简单货币汇率终结点:

setUrl('https://api.currencyfreaks.com/latest
    ?apikey=YOUR_APIKEY
    &base=GBP');
$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();
}

JSON响应将是:

{
    "date": "2020-10-06 11:22:00+00",
    "base": "GBP",
    "rates": {
        "FJD": "2.737385252915371",
        "MXN": "27.74546375788785",
        "STD": "27185.017172962733",
        "LVL": "0.8482572402792966",
        "SCR": "23.257414775003944",
        "CDF": "2535.4260357935937",
        "BBD": "2.585121591194042",
        "GTQ": "10.055244048403818",
        "CLP": "1031.8523300993463",
        "HNL": "31.82062875327341",
        "UGX": "4769.159332676713",
        "ZAR": "21.445845580346873",
        "TND": "3.542262860333636",
        "CUC": "1.2926654930214643",
        "BSD": "1.292560795597021",
        "SLL": "12676.789824444395",
        "SDG": "71.5109260164052",
        "IQD": "1542.8992384231794",
        "GMD": "66.89002117214584",
        "CUP": "34.25286108332106",
        "TWD": "37.17921872455271",
        "RSD": "128.99756740058268",
        "DOP": "75.46618143934401",
        "KMF": "540.1610026652604",
          .
          .
          .
        [179 Currencies]
    }
}

我希望它能起作用。

答案 2 :(得分:0)

加拿大银行为这些货币提供 RSS 提要: AUD、BRL、CNY、EUR、HKD、INR、IDR、JPY、MXN、NZD、NOK、PEN、RUB、SAR、SGD、ZAR、KRW、SEK、CHF、TWD、TRY、GBP、USD

这是一种无需 API 或 3rd 方服务即可获得货币换算的方法:

<?php

class EXCHANGE {

    public $Rates;
    public $Rate;

    public function __construct(){
        $this->Rates = $this->fetchAllRates();
        foreach($this->Rates as $currency => $rate){
            $this->Rate[$currency] = $rate['latest'];
        }
    }

    public function fetchAllRates(){
        $currencies = ["AUD","BRL","CNY","EUR","HKD","INR","IDR","JPY","MXN","NZD","NOK","PEN","RUB","SAR","SGD","ZAR","KRW","SEK","CHF","TWD","TRY","GBP","USD"];
        $cURL = curl_init();
        curl_setopt($cURL, CURLOPT_URL, "https://www.bankofcanada.ca/valet/observations/group/FX_RATES_DAILY/json?start_date=2010-01-01");
        curl_setopt($cURL, CURLOPT_RETURNTRANSFER, 1);
        $rates = curl_exec($cURL);
        curl_close($cURL);
        $rates = json_decode($rates,true)['observations'];
        foreach($currencies as $currency){
            foreach($rates as $rate){
                $AllRates[$currency][$rate['d']] = $rate['FX'.$currency.'CAD']['v'];
                $AllRates[$currency]['latest'] = $rate['FX'.$currency.'CAD']['v'];
            }
        }
        return $AllRates;
    }

}

$Exchange = new EXCHANGE();

foreach($Exchange->Rate as $currency => $rate){
    echo $currency.': '.$rate."<br>\n";
}

echo $Exchange->convert(2,"USD","AUD");  //2021-04-20 =  2.5767212102501