PHP 项目中使用免费汇率API获取实时汇率

PHP 项目中使用免费汇率API获取实时汇率

实时汇率对于外贸和金融行业的项目来说是很关键的,如果找人手动维护数据,费事费力费钱,也会存在出错的概率,所以用实时汇率的集成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还提供货币支持、实时历史汇率查询,这些都可以自己慢慢开发功能。

Annie整理的云服务器优惠列表

云服务商 它的优点 客官来看
阿里云 轻量云服务器38元/年(需抢)、68元/年(限购一台)、ECS云服务器99元/年(续费同价) 点击进入
腾讯云 2核2G4M 服务器新客99元/年 353元/3年 进来逛逛
UCloud 2核2G3M 轻量云主机83元/年 华盛顿/洛杉矶/圣保罗/法兰克福/伦敦90元/年 快来看看
雨云 签到1个月送一周,签到2个月0.5个月,以此类推,新人五折首购优惠 超时空跃迁
HostVDS 1核1G 云服务器0.99美元/月 实时计费 随意换ip 随时可以注销云服务器 进入,内地打开慢
LightNode 全球有45+节点,许多冷门地区,实时计费,随意换ip,随时取消 点击进入

注:以上为佣金推广链接,我们可能从中获得收益,但不会影响您的购买价格。

相关文章