튜토리얼코드

PHP에서 실시간 금 시세 조회하기

PHP에서 기본 cURL, 정확한 계산을 위한 BCMath, 429 재시도와 60초 캐시로 goldprice.dev API를 호출합니다. Composer는 필요하지 않습니다.

2026년 6월 26일 · 읽는 시간 4분

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_로 시작하는 키가 표시됩니다. 환경 변수로 설정하세요:

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.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입니다. 현물 시세를 제공하는 31개 통화 중 원하는 통화의 심볼을 spot()에 전달하세요. 정적 배열은 심볼별로 따로 캐시합니다. 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트로이온스의 가격입니다. 이후 코드는 디코딩한 배열을 사용하며, 가격은 문자열로 유지됩니다.

자주 발생하는 오류

코드증상해결 방법
401RuntimeException: goldprice: unexpected status 401 발생API 키가 없거나 유효하지 않습니다. 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로 변환해 계산하면 반올림 오차가 발생함계산 전에 가격을 (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() 메서드를 추가하고 템플릿 엔진으로 데이터를 차트에 표시하세요
  • spot()을 간단한 Laravel 또는 Symfony 서비스로 감싸고 컨테이너에 등록해 의존성을 주입하세요
  • 여러 워커가 같은 심볼을 조회한다면 If-None-Match / ETag 검사로 변경되지 않은 응답 본문을 건너뛰세요
  • bcdiv로 트로이온스를 g으로 환산해 소매용 g당 가격을 표시하세요

자주 묻는 질문

시세는 얼마나 자주 갱신되나요?

현물 시세 엔드포인트는 60초마다 갱신됩니다. 무료 플랜과 키 없는 조회는 15분 지연되며, 유료 플랜은 실시간입니다. 위의 60초 TTL은 이 주기에 맞춘 값입니다. 해당 시간 안에 spot()을 다시 호출하면 HTTP 요청 없이 캐시된 배열을 반환합니다.

자동 갱신도 무료 플랜 한도 안에서 가능한가요?

트래픽에 따라 다릅니다. 캐시가 없는 요청마다 API를 호출하면 트래픽이 많을 때 무료 플랜의 월 5,000회 한도를 빠르게 넘을 수 있습니다. APCu로 캐시를 공유해 여러 요청에 사용하세요. 시간당 몇 번 호출하는 소규모 사이트는 한도 안에서 이용할 수 있습니다. 지속적인 대량 호출은 /pricing에서 유료 플랜을 확인하세요.

상업적으로 사용할 수 있나요?

모든 플랜에서 상업적 이용이 가능합니다. 유료 플랜은 표시 의무가 없으며, 무료 플랜은 가격 근처에 goldprice.dev 링크를 눈에 보이게 표시해야 합니다.

float 대신 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 클라이언트를 만들어 주세요. Composer 없이 기본 cURL, 심볼별 60초 정적 캐시를 사용하고, 429 응답 시 대기 시간을 지수적으로 늘리며 재시도하세요. BCMath용 가격은 문자열로 유지하고 API 키는 GOLDPRICE_API_KEY에서 읽으세요. MCP 서버가 최신 스키마를 제공하므로 Claude는 처음부터 올바른 필드명을 사용할 수 있습니다.

계속 읽기

무료 API 키로 시작하기

무료 플랜으로 월 5,000회 요청할 수 있습니다. 신용카드는 필요하지 않습니다.

무료 키 받기