本文目录导读:

在 PHP 中进行汇率转换,核心思路是:获取最新汇率 → 计算转换金额。
根据你的需求(是否需要实时汇率),有以下几种实现方案:
使用免费API获取实时汇率(推荐)
这是最常用的方法,适合需要实时数据(如外贸、金融类网站)的场景,推荐使用 exchangerate-api.com 或 open.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/money 或 moneyphp/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
?>
注意事项
- 货币代码:必须使用ISO 4217标准代码(
USD、CNY、EUR等)。 - 精度问题:涉及金额计算建议使用整数(分)或
BCMath扩展,避免浮点数误差(使用round()或number_format()格式化输出)。 - 异常处理:API请求失败时要有降级方案(如使用上次缓存)。
- 法律合规:如果涉及金融交易,请使用正规汇率服务(如
exchangerate.host、currencylayer等有授权的API)。
| 场景 | 推荐方案 |
|---|---|
| 实时汇率(电商、金融机构) | 方案一(API + 缓存) |
| 内网/离线环境 | 方案二(固定汇率表) |
| 大型复杂项目 | 方案三(Composer包) |
如果你的服务器无法访问外网,可以在后台定时任务(cron)中执行方案一获取汇率到本地数据库,然后前端从数据库取数。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播