教程代码

如何在 PHP 中获取实时金价

在 PHP 中调用 goldprice.dev API,使用原生 cURL、BCMath 精确计算、429 重试和 60 秒缓存,无需 Composer。

2026年6月26日 · 阅读时间:4 分钟

要在 PHP 中获取实时金价,请使用原生 cURL 向 api.goldprice.dev/v1/spot/XAU-USD-SPOT 发送 GET 请求,并在 X-API-Key 请求头中传入 API 密钥,无需 Composer。解析 JSON 后保留价格字符串,用 BCMath 精确计算。按交易符号缓存 60 秒。免费套餐每月含 5,000 次调用,无需信用卡。已于 2026 年六月在 PHP 8.3 上测试。

获取 goldprice.dev API 密钥

前往 goldprice.dev/onboarding 注册免费账户。验证邮箱后,控制台会显示以 ga_live_ 开头的密钥。将其设为环境变量:

Shell
export GOLDPRICE_API_KEY=ga_live_replace_with_your_key_here

免费套餐每月含 5,000 次调用,支持以 31 种货币报价的黄金现货价格。无需信用卡。

确认所需扩展

无需 Composer 包。PHP 8 自带 curl 和 json,bcmath 则是用于精确十进制计算的标准扩展。请确认这三个扩展均已启用:

shell
php -m | grep -E '^(curl|json|bcmath)$'# curl# json# bcmath   <- if missing, install php8.3-bcmath (or enable in php.ini)

编写 goldprice 客户端

将代码保存为 goldprice.php。spot() 按交易符号在静态数组中缓存 60 秒,遇到 429 时按指数退避最多重试 3 次。返回解析后的数组,价格保留为字符串,供 BCMath 精确计算。

goldprice.php
<?php// php: goldprice.php, native cURL + BCMath, no Composer// curl-equivalent: https://api.goldprice.dev/v1/spot/XAU-USD-SPOTdeclare(strict_types=1);const API_BASE = 'https://api.goldprice.dev';const TIMEOUT  = 5;   // secondsconst TTL      = 60;  // secondsfinal class RateLimitedException extends RuntimeException {}final class GoldpriceClient{    private string $apiKey;    /** @var array<string, array{data: array, expires: int}> */    private static array $cache = [];    public function __construct()    {        $key = getenv('GOLDPRICE_API_KEY');        if ($key === false || $key === '') {            throw new RuntimeException('GOLDPRICE_API_KEY not set');        }        $this->apiKey = $key;    }    /**     * Fetch live spot price. Cached 60s per symbol, retries 3x on 429.     * Prices stay as strings for BCMath.     */    public function spot(string $symbol = 'XAU-USD-SPOT'): array    {        $now = time();        if (isset(self::$cache[$symbol]) && self::$cache[$symbol]['expires'] > $now) {            return self::$cache[$symbol]['data'];        }        for ($attempt = 0; $attempt < 3; $attempt++) {            try {                $data = $this->fetch($symbol);                self::$cache[$symbol] = ['data' => $data, 'expires' => $now + TTL];                return $data;            } catch (RateLimitedException) {                sleep(1 << $attempt); // 1s, 2s, 4s            }        }        throw new RateLimitedException('goldprice: 429 after 3 retries');    }    private function fetch(string $symbol): array    {        $ch = curl_init(API_BASE . '/v1/spot/' . rawurlencode($symbol));        curl_setopt_array($ch, [            CURLOPT_RETURNTRANSFER => true,            CURLOPT_TIMEOUT        => TIMEOUT,            CURLOPT_HTTPHEADER     => ['X-API-Key: ' . $this->apiKey],        ]);        $body = curl_exec($ch);        $code = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);        curl_close($ch);        if ($code === 429) {            throw new RateLimitedException('rate limited');        }        if ($code !== 200 || $body === false) {            throw new RuntimeException("goldprice: unexpected status {$code}");        }        return json_decode((string) $body, true, 512, JSON_THROW_ON_ERROR);    }}$client = new GoldpriceClient();$r = $client->spot('XAU-USD-SPOT');// Prices are strings; use BCMath for exact math (e.g. price for 5 oz):$fiveOz = bcmul($r['price'], '5', 4);printf("%s-%s: %s (computed %s)\n", $r['symbol'], $r['quote_currency'], $r['price'], $r['computed_at']);printf("5 troy oz = %s %s\n", $fiveOz, $r['quote_currency']);

运行代码

在导出 GOLDPRICE_API_KEY 的同一终端中,通过 CLI 运行文件。首次调用会请求 API,同一进程内 60 秒内的后续 spot() 调用返回缓存数组。静态缓存仅在进程内有效。在 PHP-FPM 下,可使用 APCu 或 Redis 跨请求共享缓存。

shell
php goldprice.php# XAU-USD: 4012.75 (computed 2026-10-23T07:00:18.221118+00:00)# 5 troy oz = 20063.7500 USD

切换货币或金属

交易符号格式为 METAL-CURRENCY-SPOT。可向 spot() 传入使用任意一种受支持的 31 种现货报价货币的交易符号。每个符号在静态数组中独立缓存。页面显示 5 个符号时,最多发出 5 次未命中缓存的调用,缓存有效期内再次渲染可复用结果。

goldprice.php · 多币种
$client = new GoldpriceClient();// USD spot, default$client->spot('XAU-USD-SPOT');$client->spot('XAU-INR-SPOT');$client->spot('XAU-EUR-SPOT');// Silver in USD$client->spot('XAG-USD-SPOT');

预期输出

JSON
{  "symbol": "XAU",  "quote_currency": "USD",  "unit": "troy_ounce",  "contract_type": "spot",  "price": "4012.75",  "is_stale": false,  "computed_at": "2026-10-23T07:00:18.221118+00:00"}

CLI 输出两行:交易符号、货币、价格和时间戳,以及用 BCMath 算出的 5 金衡盎司总价。下游代码使用解析后的数组,价格始终保留为字符串。

常见错误

代码现象解决方法
401出现 RuntimeException: goldprice: unexpected status 401API 密钥缺失或无效。运行 php -r 'echo getenv("GOLDPRICE_API_KEY");' 确认 PHP 能读取变量。PHP-FPM 不共享 CLI 环境变量,请通过 fastcgi_param 或进程管理器设置密钥。如果为空,请从控制台重新复制。
429按退避间隔重试三次仍返回 429,随后抛出 RateLimitedException已达到每分钟调用上限。60 秒缓存可避免稳定流量触及此限制。PHP-FPM 下的静态缓存仅限当前请求,请改用 APCu(apcu_fetch / apcu_store)跨请求共享。持续大量调用可查看 /pricing 的付费套餐。
N/A将价格转为浮点数计算时出现舍入误差计算前不要将价格转为 (float),PHP 浮点数在累加时会损失精度。保留 API 返回的字符串,使用 bcadd、bcmul 和 bccomp,并明确指定小数位数。如果提示函数未定义,请启用 bcmath 扩展。

进阶用法

  • 将静态缓存改为 apcu_store / apcu_fetch,让所有 PHP-FPM 工作进程在完整的 60 秒内复用一次获取的结果
  • 为 /v1/bars?symbol=XAU-USD-SPOT&interval=1d&from=...&to=... 添加 bars() 方法,通过模板引擎将返回的数据绘制成图表
  • 用简单的 Laravel 或 Symfony 服务封装 spot(),并绑定到容器中以便依赖注入
  • 多个工作进程轮询同一符号时,添加 If-None-Match / ETag 检查,跳过未变化的响应内容
  • 使用 bcdiv 按金衡盎司与克的换算系数计算,显示适合零售场景的每克价格

常见问题

价格多久更新一次

现货接口每隔 60 秒刷新一次,提供获授权的实时现货数据。免费套餐和免密钥价格延迟 15 分钟,付费套餐提供实时价格。上述缓存的有效期同为 60 秒,期间重复调用 spot() 会直接返回缓存数组,无需 HTTP 请求。

自动刷新会超出免费额度吗

取决于流量。如果页面在每次未命中缓存的请求中调用 API,流量较高时会很快超过每月 5,000 次的免费额度。通过 APCu 共享缓存,可让多个请求复用一次获取的结果。低流量网站每小时调用几次通常在免费额度内。持续高频使用可查看 /pricing 的付费套餐。

可以商用吗

所有套餐都允许商用。付费套餐无需添加署名链接。使用免费套餐时,必须在价格附近放置清晰可见的 goldprice.dev 链接。

为什么使用 BCMath 而不用浮点数

PHP 浮点数采用 IEEE-754 双精度格式:0.1 + 0.2 的结果是 0.30000000000000004,反复运算会累积误差。金价保留 2 位小数,用浮点数累加数千个值会产生基点级偏差。BCMath 直接处理十进制字符串,并使用固定小数位数,保证总额计算精确。

真的不需要 Composer 或 Guzzle 吗

是的。PHP 8 自带 curl 和 json,因此设置 API 密钥后,无需额外安装客户端依赖。如果已使用 Guzzle,可将 curl_* 替换为带重试中间件的 Guzzle 客户端。请求格式相同,都是带 X-API-Key 请求头的 GET 请求。

支持哪些金属

支持黄金(XAU)、白银(XAG)和铜(HG)。所有套餐均不提供铂金和钯金。替换交易符号中的金属代码即可,例如 $client->spot("XAG-USD-SPOT")。

可以让 Claude 帮我编写吗

可以。在已安装 goldprice.dev MCP 服务器的 Claude Desktop 中输入:为 goldprice.dev /v1/spot 接口编写 PHP 8 客户端。使用原生 cURL,无需 Composer。按符号设置 60 秒静态缓存,遇到 429 时按指数退避重试,保留价格字符串供 BCMath 计算。从 GOLDPRICE_API_KEY 读取 API 密钥。MCP 服务器会向 Claude 提供最新结构定义,使生成的代码首次就能使用正确的字段名。

继续阅读

从免费 API 密钥开始

免费套餐每月提供 5,000 次请求。无需信用卡。

获取免费密钥