
实时汇率对于外贸和金融行业的项目来说是很关键的,如果找人手动维护数据,费事费力费钱,也会存在出错的概率,所以用实时汇率的集成API,就可以实现调用准确的实时汇率信息,并且不会出错。
选择合适的免费汇率API
有实时汇率的API平台不少,但是我建议用iyuns的API(免费),其优点很多:
- 不需要你注册或者有API密钥,直接调用官方的就行;
- 支持全球200多种货币的实时汇率调用,基本达到了大部分项目的要求;
- 这个汇率API除了法定货币之外,还有许多加密货币的汇率;
- 有中文名称,省了很多开发代码;
- 返回JSON格式数据,解析起来十分方便。
PHP实现代码
好了,接下来我会列出完整的PHP代码,来实现调用实时汇率的功能,其中包含了错误处理以及数据解析:
<?php
/**
* 获取实时汇率数据类
* 使用免费汇率API: https://api.iyuns.com/api/allrates
*/
class ExchangeRate {
/**
* API基础URL
*/
private $apiUrl = 'https://api.iyuns.com/api/allrates';
/**
* 获取所有货币汇率数据
*
* @return array|bool 返回汇率数据数组或false(失败时)
*/
public function getAllRates() {
// 初始化cURL
$ch = curl_init();
// 设置cURL选项
curl_setopt($ch, CURLOPT_URL, $this->apiUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10); // 设置超时时间
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过SSL验证(生产环境建议开启)
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; ExchangeRate Bot/1.0)');
// 执行请求
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
// 关闭cURL
curl_close($ch);
// 检查请求是否成功
if ($error) {
error_log("cURL Error: " . $error);
return false;
}
if ($httpCode !== 200) {
error_log("HTTP Error: " . $httpCode);
return false;
}
// 解析JSON响应
$data = json_decode($response, true);
// 检查JSON解析是否成功
if (json_last_error() !== JSON_ERROR_NONE) {
error_log("JSON Decode Error: " . json_last_error_msg());
return false;
}
return $data;
}
/**
* 获取特定货币对的汇率
*
* @param string $fromCurrency 基准货币代码(如USD)
* @param string $toCurrency 目标货币代码(如CNY)
* @return float|bool 返回汇率值或false(失败时)
*/
public function getRate($fromCurrency, $toCurrency) {
// 获取所有汇率数据
$rates = $this->getAllRates();
if (!$rates) {
return false;
}
// 检查基准货币是否存在
if (!isset($rates[$fromCurrency])) {
error_log("Base currency {$fromCurrency} not found");
return false;
}
// 检查目标货币是否存在
if (!isset($rates[$toCurrency])) {
error_log("Target currency {$toCurrency} not found");
return false;
}
// 计算汇率(假设API返回的是相对于某个基准的汇率)
// 这里简化处理,实际可能需要根据API返回结构调整
$baseRate = $rates[$fromCurrency];
$targetRate = $rates[$toCurrency];
// 如果基准货币是CNY,则直接返回目标货币的汇率
if ($fromCurrency === 'CNY') {
return $targetRate;
}
// 如果目标货币是CNY,则返回1/基准货币汇率
if ($toCurrency === 'CNY') {
return 1 / $baseRate;
}
// 其他情况:通过CNY作为中介计算
return $targetRate / $baseRate;
}
/**
* 货币转换
*
* @param float $amount 金额
* @param string $fromCurrency 原货币
* @param string $toCurrency 目标货币
* @return float|bool 转换后的金额或false(失败时)
*/
public function convert($amount, $fromCurrency, $toCurrency) {
if ($fromCurrency === $toCurrency) {
return $amount;
}
$rate = $this->getRate($fromCurrency, $toCurrency);
if ($rate === false) {
return false;
}
return $amount * $rate;
}
}
// 使用示例
try {
$exchange = new ExchangeRate();
// 获取所有汇率
echo "<h3>所有可用货币汇率(以CNY为基准):</h3>\n";
$allRates = $exchange->getAllRates();
if ($allRates) {
echo "<table border='1'>\n";
echo "<tr><th>货币代码</th><th>货币名称</th><th>汇率(CNY)</th></tr>\n";
// 显示前10个货币作为示例
$count = 0;
foreach ($allRates as $code => $rate) {
if ($count >= 10) break;
// 根据常见货币代码推断货币名称(实际应用中应有完整映射表)
$currencyNames = [
'CNY' => '人民币',
'USD' => '美元',
'EUR' => '欧元',
'JPY' => '日元',
'GBP' => '英镑',
'AUD' => '澳元',
'CAD' => '加元',
'CHF' => '瑞士法郎',
'HKD' => '港币',
'SGD' => '新加坡元'
];
$name = isset($currencyNames[$code]) ? $currencyNames[$code] : $code;
echo "<tr><td>{$code}</td><td>{$name}</td><td>" . number_format($rate, 4) . "</td></tr>\n";
$count++;
}
echo "</table>\n";
} else {
echo "<p>无法获取汇率数据,请稍后重试。</p>\n";
}
// 货币转换示例
echo "<h3>货币转换示例:</h3>\n";
$amount = 100;
$from = 'USD';
$to = 'CNY';
$converted = $exchange->convert($amount, $from, $to);
if ($converted !== false) {
$rate = $exchange->getRate($from, $to);
echo "<p>{$amount} {$from} = " . number_format($converted, 2) . " {$to} (汇率: " . number_format($rate, 4) . ")</p>\n";
} else {
echo "<p>货币转换失败。</p>\n";
}
} catch (Exception $e) {
echo "<p>发生错误: " . $e->getMessage() . "</p>\n";
}
?>
缓存优化建议
但是这个汇率API毕竟是免费的,肯定是限制了调用频率,防止别人的恶意调用,所以我们在实际的项目开发之中,需要添加缓存机制:
<?php
/**
* 带缓存的汇率获取类
*/
class CachedExchangeRate extends ExchangeRate {
private $cacheFile = 'exchange_rates_cache.json';
private $cacheTime = 3600; // 缓存1小时(秒)
public function getAllRates() {
// 检查缓存文件是否存在且未过期
if (file_exists($this->cacheFile)) {
$cacheData = json_decode(file_get_contents($this->cacheFile), true);
if (time() - $cacheData['timestamp'] < $this->cacheTime) {
return $cacheData['rates'];
}
}
// 获取新数据
$rates = parent::getAllRates();
if ($rates) {
// 保存到缓存
$cacheData = [
'timestamp' => time(),
'rates' => $rates
];
file_put_contents($this->cacheFile, json_encode($cacheData));
}
return $rates;
}
}
?>
注意事项
- API限制:免费API会有调用频率的限制,所以需要使用缓存避免重复请求;
- 错误处理:网络请求不一定会成功,添加完善的错误处理机制,提高调用的效率;
- 数据验证:对于API返回的数据最好进行验证,防止数据错误导致程序异常,程序异常会让后续的工作都没办法完成;
- 备用方案:别只把目光放在一个平台的API上面,最好是集成多个汇率API作为备胎,提高程序的稳定;
- HTTPS安全:现在基本都需要SSL验证,保证你的程序的数据传输安全。
其实调用汇率API是不难的,使用php语言是可以很轻松的实现这个功能,也能够达到货币转换的功能。
并且一般汇率API还提供货币支持、实时历史汇率查询,这些都可以自己慢慢开发功能。
