PHPでリアルタイムの金価格を取得するには、標準のcURLでapi.goldprice.dev/v1/spot/XAU-USD-SPOTにGETリクエストを送ります。APIキーはX-API-Keyヘッダーに指定します。Composerは不要です。JSONをデコードし、価格は文字列のままBCMathで正確に計算します。銘柄ごとに60秒間キャッシュします。無料プランは月5,000回までで、クレジットカードは不要です。2026年6月にPHP 8.3で動作確認済みです。
goldprice.devのAPIキーを取得する
goldprice.dev/onboardingで無料アカウントを作成します。メール認証後、ダッシュボードにga_live_で始まるキーが表示されます。環境変数に設定します。
export GOLDPRICE_API_KEY=ga_live_replace_with_your_key_here無料プランでは月5,000回まで呼び出せます。金のスポット価格は31通貨に対応しています。クレジットカードは不要です。
必要な拡張機能を確認する
Composerパッケージは不要です。curlとjsonはPHP 8に含まれ、bcmathは正確な小数計算に使う標準拡張機能です。すべて有効になっているか確認します。
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で正確に計算できます。
<?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を使います。
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です。対応する31通貨の銘柄をspot()に渡します。静的配列では銘柄ごとにキャッシュします。5銘柄を表示するページでは、キャッシュがなければ最大5回呼び出し、有効期間内の次の描画では再利用します。
$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');出力例
{ "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 401が出る | APIキーが未設定か無効です。php -r 'echo getenv("GOLDPRICE_API_KEY");'でPHPから環境変数を読めるか確認します。PHP-FPMにはCLIの環境変数が共有されないため、fastcgi_paramやプロセスマネージャーで設定します。値が空ならダッシュボードからキーをコピーし直してください。 |
| 429 | 待機を挟んで3回再試行しても429が返り、RateLimitedExceptionが発生する | 分あたりの上限に達しています。一定のアクセスには60秒キャッシュが有効です。PHP-FPMの静的キャッシュはリクエスト単位なので、APCuのapcu_fetchとapcu_storeに置き換えて共有します。大量の呼び出しを継続する場合は、/pricingで有料プランを確認してください。 |
| N/A | 価格をfloatに変換して計算すると丸め誤差が出る | 計算前に価格を(float)へ変換しないでください。PHPの浮動小数点数は合計時に精度が失われます。APIが返す文字列を保ち、小数点以下の桁数を明示してbcadd、bcmul、bccompを使います。関数が未定義ならbcmath拡張機能を有効にします。 |
活用方法
- 静的キャッシュを
apcu_storeとapcu_fetchに置き換え、取得した価格を60秒間すべてのPHP-FPMワーカーで共有します /v1/bars?symbol=XAU-USD-SPOT&interval=1d&from=...&to=...用のbars()メソッドを追加し、テンプレートエンジンでデータをグラフにしますspot()をLaravelやSymfonyの小さなサービスにまとめ、コンテナに登録して依存性注入で使います- 複数のワーカーが同じ銘柄を取得する場合は、
If-None-MatchとETagの確認を追加し、変更のないデータの受信を省きます bcdivとトロイオンスからグラムへの換算係数を使い、小売向けにグラム単価を表示します