PHP 怎么汇率转换

wen PHP项目 1

本文目录导读:

PHP 怎么汇率转换

  1. 方案一:使用免费API获取实时汇率(推荐)
  2. 方案二:使用固定汇率(离线 / 手动更新)
  3. 方案三:使用Composer包(功能全面)
  4. 注意事项

在 PHP 中进行汇率转换,核心思路是:获取最新汇率 → 计算转换金额

根据你的需求(是否需要实时汇率),有以下几种实现方案:


使用免费API获取实时汇率(推荐)

这是最常用的方法,适合需要实时数据(如外贸、金融类网站)的场景,推荐使用 exchangerate-api.comopen.er-api.com(免费且无需密钥)。

完整代码示例(使用 file_get_contents)

<?php
/**
 * 获取实时汇率并转换
 * @param float $amount       金额
 * @param string $from        原货币(如 USD)
 * @param string $to          目标货币(如 CNY)
 * @return float|string       转换后金额,失败返回错误信息
 */
function convertCurrency($amount, $from, $to) {
    // 1. 调用API获取最新汇率(以USD为基准)
    $api_url = "https://open.er-api.com/v6/latest/USD";
    try {
        // 2. 获取数据(如果服务器禁用了 file_get_contents,改用 cURL)
        $response = file_get_contents($api_url);
        if ($response === false) {
            throw new Exception("无法连接汇率服务");
        }
        $data = json_decode($response, true);
        if ($data['result'] !== 'success') {
            throw new Exception("汇率获取失败");
        }
        // 3. 检查货币代码是否有效
        $rates = $data['rates'];
        if (!isset($rates[$from]) || !isset($rates[$to])) {
            throw new Exception("不支持的货币代码");
        }
        // 4. 计算交叉汇率(先转USD,再转目标货币)
        $amount_in_usd = $amount / $rates[$from];
        $converted = $amount_in_usd * $rates[$to];
        // 5. 格式化保留2位小数
        return round($converted, 2);
    } catch (Exception $e) {
        // 失败时返回错误信息(生产环境建议记录日志)
        return "Error: " . $e->getMessage();
    }
}
// 使用示例:将100美元转换为人民币
echo convertCurrency(100, 'USD', 'CNY'); 
// 输出示例:719.32(取决于当前汇率)
?>

更健壮的版本(使用 cURL + 缓存)

很多服务器不允许 file_get_contents 访问外网,且频繁请求API会变慢,推荐用 cURL + 缓存

<?php
function getExchangeRate($from, $to) {
    $cache_file = __DIR__ . '/rates_cache.json';
    $cache_time = 3600; // 缓存1小时
    // 1. 检查缓存是否存在且未过期
    if (file_exists($cache_file) && (time() - filemtime($cache_file) < $cache_time)) {
        $cached = json_decode(file_get_contents($cache_file), true);
    } else {
        // 2. 使用cURL获取新数据
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, "https://open.er-api.com/v6/latest/USD");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        $response = curl_exec($ch);
        $error = curl_error($ch);
        curl_close($ch);
        if ($response === false) {
            throw new Exception("cURL Error: " . $error);
        }
        $data = json_decode($response, true);
        if ($data['result'] !== 'success') {
            throw new Exception("API Error: " . ($data['error-type'] ?? 'unknown'));
        }
        // 3. 写入缓存
        file_put_contents($cache_file, json_encode($data));
        $cached = $data;
    }
    $rates = $cached['rates'];
    if (!isset($rates[$from]) || !isset($rates[$to])) {
        throw new Exception("货币代码无效: {$from} -> {$to}");
    }
    // 计算交叉汇率
    $rate = $rates[$to] / $rates[$from];
    return $rate;
}
// 使用
try {
    $rate = getExchangeRate('USD', 'EUR');
    echo "1 USD = " . $rate . " EUR<br>";
    echo "100 USD = " . round(100 * $rate, 2) . " EUR";
} catch (Exception $e) {
    echo "错误:" . $e->getMessage();
}
?>

使用固定汇率(离线 / 手动更新)

如果项目不需要实时汇率,或者内网环境无法访问外网,可以使用硬编码汇率表(定期手动更新)。

<?php
class CurrencyConverter {
    // 基准汇率(以USD = 1为基准,手动维护)
    private static $rates = [
        'USD' => 1.0,
        'CNY' => 7.19,    // 人民币
        'EUR' => 0.92,    // 欧元
        'JPY' => 149.50,  // 日元
        'GBP' => 0.79,    // 英镑
        'HKD' => 7.83,    // 港币
        'AUD' => 1.53,    // 澳元
        'CAD' => 1.36,    // 加元
        'CHF' => 0.88,    // 瑞士法郎
    ];
    public static function convert($amount, $from, $to) {
        if (!isset(self::$rates[$from]) || !isset(self::$rates[$to])) {
            return null;
        }
        // 转成USD再转目标
        $usd_amount = $amount / self::$rates[$from];
        return round($usd_amount * self::$rates[$to], 2);
    }
    // 显示当前汇率表
    public static function showRates() {
        foreach (self::$rates as $code => $rate) {
            echo "USD 1 = {$code} {$rate}<br>";
        }
    }
}
// 使用
echo CurrencyConverter::convert(100, 'USD', 'CNY'); // 719
?>

使用Composer包(功能全面)

如果项目较大,建议使用成熟的PHP库,如 brick/moneymoneyphp/money,但这类库通常还需要配合汇率服务。

安装示例(moneyphp/money):

composer require moneyphp/money
<?php
use Money\Money;
use Money\Currency;
use Money\Exchange\FixedExchange;
use Money\Converter;
// 定义固定汇率
$exchange = new FixedExchange([
    'USD' => [
        'CNY' => '7.19',
    ],
    'CNY' => [
        'USD' => '0.139',
    ],
]);
$converter = new Converter($exchange);
$money = new Money(10000, new Currency('USD')); // 金额单位是分
$converted = $converter->convert($money, new Currency('CNY'));
echo $converted->getAmount(); // 71900
?>

注意事项

  1. 货币代码:必须使用ISO 4217标准代码(USDCNYEUR等)。
  2. 精度问题:涉及金额计算建议使用整数(分)或 BCMath 扩展,避免浮点数误差(使用 round()number_format() 格式化输出)。
  3. 异常处理:API请求失败时要有降级方案(如使用上次缓存)。
  4. 法律合规:如果涉及金融交易,请使用正规汇率服务(如 exchangerate.hostcurrencylayer 等有授权的API)。

场景 推荐方案
实时汇率(电商、金融机构) 方案一(API + 缓存)
内网/离线环境 方案二(固定汇率表)
大型复杂项目 方案三(Composer包)

如果你的服务器无法访问外网,可以在后台定时任务(cron)中执行方案一获取汇率到本地数据库,然后前端从数据库取数。

抱歉,评论功能暂时关闭!