Pobieranie danych z API (cURL + JSON) na przykładzie kursów NBP
- WWW i API
- poziom: średni
- aktualizacja: 12 lipca 2026
Prędzej czy później każda strona potrzebuje danych z zewnątrz: kursów walut, pogody, danych z własnej aplikacji. Ten skrypt zawiera solidną funkcję pobierz_json() z poprawną obsługą błędów oraz wariant z buforowaniem, żeby nie odpytywać API przy każdym wejściu na stronę.
Za przykład służy darmowe, publiczne API Narodowego Banku Polskiego — nie wymaga klucza ani rejestracji.
<?php
/**
* Pobieranie danych z API (cURL + JSON) — skryptyPHP.com
* Zapisz jako: kursy-walut.php
* Wymaga rozszerzenia curl (standard na hostingach).
*/
/**
* Pobiera i dekoduje JSON spod wskazanego adresu.
*
* @throws RuntimeException gdy połączenie lub dekodowanie się nie powiedzie
*/
function pobierz_json(string $url, int $limitCzasu = 10): array
{
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true, // zwróć odpowiedź, nie wypisuj
CURLOPT_TIMEOUT => $limitCzasu, // maks. czas całego pobierania
CURLOPT_CONNECTTIMEOUT => 5, // maks. czas łączenia
CURLOPT_FOLLOWLOCATION => true, // podążaj za przekierowaniami
CURLOPT_MAXREDIRS => 3,
CURLOPT_USERAGENT => 'MojaStrona/1.0 (+https://twojadomena.pl)',
CURLOPT_HTTPHEADER => ['Accept: application/json'],
// Weryfikacja certyfikatu SSL zostaje WŁĄCZONA (domyślna).
// Nigdy nie wyłączaj jej przez CURLOPT_SSL_VERIFYPEER => false!
]);
$odpowiedz = curl_exec($ch);
if ($odpowiedz === false) {
$blad = curl_error($ch);
curl_close($ch);
throw new RuntimeException('Błąd połączenia: ' . $blad);
}
$kodHttp = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($kodHttp >= 400) {
throw new RuntimeException('Serwer API zwrócił błąd HTTP ' . $kodHttp);
}
try {
return json_decode($odpowiedz, true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
throw new RuntimeException('Nieprawidłowy JSON: ' . $e->getMessage());
}
}
/**
* Jak wyżej, ale z buforowaniem odpowiedzi do pliku.
* Kolejne wywołania w czasie $czasWaznosci czytają z dysku, nie z sieci.
*/
function pobierz_json_z_cache(
string $url,
string $plikCache,
int $czasWaznosci = 3600
): array {
if (is_file($plikCache) && time() - filemtime($plikCache) < $czasWaznosci) {
$dane = json_decode((string) file_get_contents($plikCache), true);
if (is_array($dane)) {
return $dane;
}
}
$dane = pobierz_json($url);
file_put_contents($plikCache, json_encode($dane), LOCK_EX);
return $dane;
}
// ── PRZYKŁAD: kursy walut z API NBP ─────────────────────────
$interesujace = ['USD', 'EUR', 'CHF', 'GBP'];
try {
$tabela = pobierz_json_z_cache(
'https://api.nbp.pl/api/exchangerates/tables/A?format=json',
__DIR__ . '/cache-nbp.json',
3600 // odświeżaj co godzinę
);
echo '<h2>Kursy średnie NBP (tabela ' . htmlspecialchars($tabela[0]['no']) . ')</h2>';
echo '<ul>';
foreach ($tabela[0]['rates'] as $kurs) {
if (in_array($kurs['code'], $interesujace, true)) {
echo '<li>1 ' . htmlspecialchars($kurs['code']) . ' = '
. number_format($kurs['mid'], 4, ',', ' ') . ' zł</li>';
}
}
echo '</ul>';
} catch (RuntimeException $e) {
// Na produkcji: zaloguj błąd i pokaż neutralny komunikat
error_log('Kursy NBP: ' . $e->getMessage());
echo '<p>Kursy walut są chwilowo niedostępne.</p>';
}
Jak użyć tego skryptu
- Zapisz kod jako
kursy-walut.phpi otwórz w przeglądarce — kursy pobiorą się z API NBP. - Do własnego API zmień adres URL i strukturę odczytu danych (tablica
$tabela). - Funkcja z buforem zapisuje odpowiedź w pliku
cache-nbp.json— katalog musi być zapisywalny dla PHP. - Czas ważności bufora dobierz do danych: kursy walut wystarczy odświeżać co godzinę, pogodę co 15 minut.
Warto wiedzieć
- Zawsze ustawiaj limity czasu — bez nich awaria zewnętrznego API potrafi „powiesić" całą Twoją stronę.
- Nigdy nie wyłączaj weryfikacji SSL (
CURLOPT_SSL_VERIFYPEER). Jeśli hosting zgłasza problem z certyfikatami, poproś administrację o aktualizację paczki CA. - Buforowanie chroni Cię przed limitami zapytań API i przyspiesza stronę — odpowiedź z dysku to ułamek milisekundy.
JSON_THROW_ON_ERRORzamienia ciche błędy dekodowania na wyjątki — nie przegapisz zepsutej odpowiedzi.
Podobne skrypty
Własny skracacz linków (bez bazy danych)
Miniskracacz URL w jednym pliku: krótkie kody generowane z random_int(), zapis w pliku JSON z blokadą, przekierowania 301 i licznik kliknięć.
średni Zobacz kod → WWW i APIGenerator mapy strony (sitemap.xml)
Generowanie sitemap.xml dla wyszukiwarek: strony statyczne z tablicy plus wpisy dynamiczne z bazy danych, poprawne kodowanie XML i daty ostatniej modyfikacji.
średni Zobacz kod → WWW i APIObsługa ciasteczek (cookies) + baner zgody bez JavaScriptu
Nowoczesna obsługa cookies w PHP: zapis z flagami SameSite/Secure/HttpOnly, odczyt, usuwanie oraz prosty baner informacyjny o ciasteczkach działający bez JavaScriptu.
początkujący Zobacz kod →