この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:4
ページ更新者:guest
更新日時:2026-06-11 07:07:02

タイトル: APIを呼び出す方法
SEOタイトル: PHP で API を呼び出す方法 完全ガイド(cURL / file_get_contents / Guzzle / GET / POST / JSON / エラーハンドリング)

この記事の要点
  • PHP から HTTP API を呼ぶ主な方法は cURL(curl_*) / file_get_contents + ストリームコンテキスト / Guzzle の 3 系統
  • 最も柔軟で実戦的なのは cURL。タイムアウト・ヘッダ・SSL 検証など細かい制御ができる
  • GET / POST / PUT / DELETE は CURLOPT_CUSTOMREQUESTCURLOPT_POSTFIELDS で指定
  • JSON API は リクエストで json_encode、レスポンスで json_decode がセット
  • SSL 検証無効化(VERIFYPEER=false)は本番禁止。証明書バンドルを正しく指定する

PHP から API を呼ぶ 3 つの方法

方式長所短所
cURL(curl_*柔軟、高速、ヘッダや SSL を細かく制御コードがやや冗長
file_get_contents + コンテキスト1 行で書けるPOST / ヘッダがやや書きにくい、allow_url_fopen 必要
Guzzle(HTTP クライアントライブラリ)API がモダン、非同期 / リトライ / ミドルウェア対応Composer 必須

方法 1: cURL で GET

$apiUrl = 'https://api.example.com/users/1';

$curl = curl_init();
curl_setopt_array($curl, [
    CURLOPT_URL            => $apiUrl,
    CURLOPT_CUSTOMREQUEST  => 'GET',
    CURLOPT_RETURNTRANSFER => true,   // 結果を文字列で返す
    CURLOPT_TIMEOUT        => 10,     // タイムアウト 10 秒
    CURLOPT_CONNECTTIMEOUT => 5,
    CURLOPT_FOLLOWLOCATION => true,   // リダイレクト追従
    CURLOPT_HTTPHEADER     => [
        'Accept: application/json',
        'Authorization: Bearer ' . $token,
    ],
]);

$response = curl_exec($curl);
$status   = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$err      = curl_error($curl);
curl_close($curl);

if ($response === false) {
    throw new RuntimeException('cURL error: ' . $err);
}
if ($status >= 400) {
    throw new RuntimeException("HTTP $status: $response");
}

$data = json_decode($response, true);
print_r($data);

方法 2: cURL で POST(JSON ボディ)

$apiUrl  = 'https://api.example.com/users';
$payload = json_encode([
    'name'  => '山田太郎',
    'email' => 'taro@example.com',
], JSON_UNESCAPED_UNICODE);

$curl = curl_init();
curl_setopt_array($curl, [
    CURLOPT_URL            => $apiUrl,
    CURLOPT_CUSTOMREQUEST  => 'POST',
    CURLOPT_POSTFIELDS     => $payload,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        'Content-Type: application/json',
        'Accept: application/json',
        'Content-Length: ' . strlen($payload),
    ],
    CURLOPT_TIMEOUT        => 10,
]);

$response = curl_exec($curl);
$status   = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);

方法 3: cURL で PUT / DELETE

// PUT
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));

// DELETE
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');

方法 4: file_get_contents で簡易呼び出し

// GET
$response = file_get_contents('https://api.example.com/items');
$data = json_decode($response, true);

// POST(ストリームコンテキスト)
$options = [
    'http' => [
        'method'  => 'POST',
        'header'  => "Content-Type: application/json\r\n" .
                     "Accept: application/json\r\n",
        'content' => json_encode(['name' => 'apple']),
        'timeout' => 10,
        'ignore_errors' => true,  // 4xx / 5xx でも本文を取得
    ],
];
$ctx = stream_context_create($options);
$response = file_get_contents('https://api.example.com/items', false, $ctx);

// レスポンスヘッダは $http_response_header に自動で入る
print_r($http_response_header);

注意: file_get_contents での URL 取得は allow_url_fopen=On が必要です。本番サーバではセキュリティ上オフにする運用もあるため、その場合は cURL を使います。

方法 5: Guzzle(推奨・モダン)

composer require guzzlehttp/guzzle
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

$client = new Client([
    'base_uri' => 'https://api.example.com/',
    'timeout'  => 10,
    'headers'  => [
        'Authorization' => 'Bearer ' . $token,
        'Accept'        => 'application/json',
    ],
]);

try {
    // GET
    $res  = $client->get('users/1');
    $user = json_decode($res->getBody(), true);

    // POST (json オプションが自動エンコード)
    $res = $client->post('users', [
        'json' => ['name' => '山田', 'email' => 'taro@example.com'],
    ]);

    // クエリパラメータ
    $res = $client->get('users', [
        'query' => ['page' => 2, 'limit' => 20],
    ]);
} catch (RequestException $e) {
    error_log('API error: ' . $e->getMessage());
    if ($e->hasResponse()) {
        error_log('Body: ' . $e->getResponse()->getBody());
    }
}

クエリパラメータの組み立て

$params = ['q' => 'PHP cURL', 'lang' => 'ja', 'page' => 2];
$url    = 'https://api.example.com/search?' . http_build_query($params);
// → https://api.example.com/search?q=PHP+cURL&lang=ja&page=2

SSL 証明書の扱い(重要)

古いサンプルでよくある CURLOPT_SSL_VERIFYPEER = false本番投入禁止です。中間者攻撃(MITM)に対し丸腰になります。社内自己署名 CA を使う場合は明示的に CA バンドルを指定します。

// 正しい指定(公的 CA バンドル)
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($curl, CURLOPT_CAINFO, '/etc/ssl/certs/ca-certificates.crt');

// 自己署名 CA を使うケースのみ
curl_setopt($curl, CURLOPT_CAINFO, '/path/to/internal-ca.pem');

タイムアウトとリトライ

オプション意味推奨値
CURLOPT_CONNECTTIMEOUT接続確立までの上限3〜5 秒
CURLOPT_TIMEOUT処理全体の上限10〜30 秒

5xx / ネットワークエラー時のリトライは指数バックオフで 2〜3 回が目安。POST 系の非冪等なリクエストはリトライしない(同じ処理が二重実行される)。

ステータスコード別の処理

switch (true) {
    case $status >= 200 && $status < 300:
        // 成功
        break;
    case $status === 401 || $status === 403:
        throw new AuthException('認証エラー');
    case $status === 404:
        throw new NotFoundException('リソース無し');
    case $status === 429:
        // レート制限 → Retry-After に従って待機
        break;
    case $status >= 500:
        throw new ServerException('サーバ側エラー');
    default:
        throw new ApiException("Unexpected $status");
}

セキュリティのチェックリスト

  • API キー / トークンは環境変数.env)に置き、コードに直書きしない
  • SSL_VERIFYPEERtrueのまま
  • レスポンスをそのままユーザーに出力する場合はエスケープ必須
  • 外部 URL を動的に組み立てる場合は SSRF 対策(プライベート IP への接続禁止など)
  • ログにトークンを出さない

関連

  • API
  • REST
  • cURL / curl_init / curl_exec
  • json_encode / json_decode
  • Guzzle HTTP クライアント