Hướng dẫnLập trình

Cách lấy giá vàng trực tiếp bằng PHP

Gọi API goldprice.dev từ PHP bằng cURL gốc, tính chính xác với BCMath, thử lại khi gặp 429 và lưu đệm 60 giây, không cần Composer.

26 thg 6, 2026 · 4 phút đọc

Để lấy giá vàng trực tiếp trong PHP, dùng cURL gốc gửi GET đến api.goldprice.dev/v1/spot/XAU-USD-SPOT kèm khóa API trong header X-API-Key, không cần Composer. Giải mã JSON, giữ giá dạng chuỗi và tính chính xác bằng BCMath. Lưu đệm từng mã 60 giây. Gói Free có 5.000 lượt gọi/tháng, không cần thẻ tín dụng. Đã kiểm thử tháng Sáu 2026 trên PHP 8.3.

Lấy khóa API goldprice.dev

Đăng ký miễn phí tại goldprice.dev/onboarding. Sau khi xác nhận email, bạn sẽ thấy khóa bắt đầu bằng ga_live_ trên bảng điều khiển. Đặt khóa làm biến môi trường:

Shell
export GOLDPRICE_API_KEY=ga_live_replace_with_your_key_here

Gói Free có 5.000 lượt gọi/tháng và giá vàng giao ngay bằng 31 loại tiền. Không cần thẻ tín dụng.

Kiểm tra các phần mở rộng cần thiết

Không cần gói Composer. PHP 8 có curl và json; bcmath là phần mở rộng tiêu chuẩn để tính số thập phân chính xác. Kiểm tra cả ba đã được bật:

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

Viết mã gọi goldprice

Lưu thành goldprice.php. spot() lưu đệm từng mã trong mảng tĩnh 60 giây, thử lại tối đa 3 lần khi gặp 429 với thời gian chờ tăng theo cấp số nhân. Hàm trả mảng đã giải mã, giữ giá dạng chuỗi để BCMath tính chính xác.

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']);

Chạy mã

Chạy tệp bằng CLI trong shell đã đặt GOLDPRICE_API_KEY. Lần đầu gọi API; các lần gọi spot() cùng tiến trình trong 60 giây trả mảng đã lưu. Bộ nhớ đệm tĩnh thuộc từng tiến trình. Dùng APCu hoặc Redis để chia sẻ giữa các yêu cầu PHP-FPM.

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

Đổi tiền tệ hoặc kim loại

Mã có dạng METAL-CURRENCY-SPOT. Truyền mã dùng bất kỳ loại tiền nào trong 31 loại được hỗ trợ vào spot(). Mỗi mã được lưu riêng trong mảng tĩnh. Trang hiển thị 5 mã gọi tối đa 5 lượt chưa lưu đệm, rồi dùng lại khi hiển thị trong thời hạn.

goldprice.php · Đa tiền tệ
$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');

Kết quả mong đợi

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 in hai dòng: mã/tiền tệ/giá/dấu thời gian và kết quả BCMath cho 5 ounce troy. Mã xử lý tiếp theo dùng mảng đã giải mã, giá vẫn là chuỗi.

Lỗi thường gặp

MãBiểu hiệnCách sửa
401RuntimeException: goldprice: unexpected status 401Thiếu khóa API hoặc khóa không hợp lệ. Kiểm tra PHP nhận được biến: php -r 'echo getenv("GOLDPRICE_API_KEY");'. PHP-FPM không dùng chung biến môi trường CLI. Đặt khóa qua fastcgi_param hoặc trình quản lý tiến trình. Nếu trống, sao chép lại từ bảng điều khiển.
429Cả ba lần thử lại đều nhận 429, sau đó phát sinh RateLimitedExceptionBạn đã chạm giới hạn mỗi phút. Bộ nhớ đệm 60 giây giúp tránh lỗi với lưu lượng đều. Trong PHP-FPM, bộ nhớ đệm tĩnh chỉ tồn tại trong từng yêu cầu. Dùng APCu (apcu_fetch / apcu_store) để chia sẻ. Với lưu lượng lớn liên tục, xem gói trả phí tại /pricing.
N/ACó sai số làm tròn khi ép giá sang float để tínhKhông ép giá sang (float) trước khi tính vì float của PHP mất độ chính xác khi cộng. Giữ chuỗi API trả về và dùng bcadd, bcmul, bccomp với số chữ số thập phân được chỉ định. Bật phần mở rộng bcmath nếu các hàm chưa được định nghĩa.

Làm thêm

  • Thay bộ nhớ đệm tĩnh bằng apcu_store / apcu_fetch để các worker PHP-FPM dùng chung kết quả trong 60 giây
  • Thêm phương thức bars() gọi /v1/bars?symbol=XAU-USD-SPOT&interval=1d&from=...&to=... và vẽ biểu đồ bằng công cụ mẫu giao diện
  • Bọc spot() trong dịch vụ Laravel hoặc Symfony đơn giản, đăng ký vào container để tiêm phụ thuộc
  • Thêm kiểm tra If-None-Match / ETag khi nhiều worker truy vấn cùng mã để bỏ qua dữ liệu không đổi
  • Dùng bcdiv với hệ số đổi ounce troy sang gam để hiển thị giá bán lẻ mỗi gram

Câu hỏi

Giá cập nhật bao lâu một lần?

Endpoint giao ngay cập nhật mỗi 60 giây. Gói Free và truy cập không khóa chậm 15 phút; gói trả phí có giá trực tiếp. TTL 60 giây khớp nhịp này, nên gọi lại spot() trong thời hạn sẽ nhận mảng từ bộ nhớ đệm, không gửi yêu cầu HTTP.

Tự động cập nhật có nằm trong giới hạn gói Free không?

Tùy lưu lượng. Gọi API mỗi yêu cầu chưa lưu đệm có thể nhanh chóng vượt 5.000 lượt/tháng của gói Free. Dùng APCu để chia sẻ kết quả. Trang ít truy cập, chỉ gọi vài lần mỗi giờ vẫn trong giới hạn Free. Với lưu lượng lớn liên tục, xem gói trả phí tại /pricing.

Có được dùng cho mục đích thương mại không?

Mọi gói đều cho phép sử dụng thương mại. Gói trả phí không cần liên kết ghi công; gói Free yêu cầu liên kết goldprice.dev dễ thấy gần giá.

Vì sao dùng BCMath thay cho float?

Float PHP là số thực IEEE-754: 0.1 + 0.2 bằng 0.30000000000000004. Sai số tích lũy qua nhiều phép tính. Giá vàng có 2 chữ số thập phân; cộng hàng nghìn giá trị có thể lệch ở mức điểm cơ bản. BCMath tính trực tiếp trên chuỗi thập phân với độ chính xác cố định.

Thực sự không cần Composer hoặc Guzzle sao?

Đúng. PHP 8 có curl và json, nên chỉ cần khóa API để dùng client. Nếu đã dùng Guzzle, thay curl_* bằng client Guzzle có middleware thử lại. Yêu cầu vẫn là GET kèm header X-API-Key.

Hỗ trợ những kim loại nào?

Hỗ trợ vàng (XAU), bạc (XAG), đồng (HG). Không gói nào có bạch kim hoặc palladium. Đổi mã kim loại trong mã giao dịch, ví dụ $client->spot("XAG-USD-SPOT").

Có thể nhờ Claude viết mã này không?

Có. Mở Claude Desktop đã cài máy chủ MCP goldprice.dev và yêu cầu: Viết client PHP 8 cho endpoint /v1/spot của goldprice.dev. Dùng cURL gốc, không Composer, lưu đệm tĩnh từng mã 60 giây, thử lại khi gặp 429 với thời gian chờ tăng theo cấp số nhân. Giữ giá dạng chuỗi cho BCMath. Đọc khóa API từ GOLDPRICE_API_KEY. MCP cung cấp schema hiện hành để Claude dùng đúng tên trường.

Đọc tiếp

Bắt đầu với khóa API miễn phí

5.000 yêu cầu mỗi tháng trên gói miễn phí. Không cần thẻ tín dụng.

Lấy khóa miễn phí