Przejdź do treści

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 95 linii Pobierz .php
<?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

  1. Zapisz kod jako kursy-walut.php i otwórz w przeglądarce — kursy pobiorą się z API NBP.
  2. Do własnego API zmień adres URL i strukturę odczytu danych (tablica $tabela).
  3. Funkcja z buforem zapisuje odpowiedź w pliku cache-nbp.json — katalog musi być zapisywalny dla PHP.
  4. 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_ERROR zamienia ciche błędy dekodowania na wyjątki — nie przegapisz zepsutej odpowiedzi.
#curl #api #json #nbp #cache

Podobne skrypty