Để 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:
export GOLDPRICE_API_KEY=ga_live_replace_with_your_key_hereGó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:
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.
<?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.
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.
$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
{ "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ện | Cách sửa |
|---|---|---|
| 401 | RuntimeException: goldprice: unexpected status 401 | Thiế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. |
| 429 | Cả ba lần thử lại đều nhận 429, sau đó phát sinh RateLimitedException | Bạ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/A | Có sai số làm tròn khi ép giá sang float để tính | Khô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
bcdivvới hệ số đổi ounce troy sang gam để hiển thị giá bán lẻ mỗi gram