外部APIと通信するとき、ヘッダー情報にはステータスコードやコンテンツタイプ、認証情報、キャッシュ制御など重要な情報が含まれています。これを正しく取得できれば、エラー処理やデバッグ、レスポンスの解析が格段にしやすくなります。このページではPHPでcURLを使ってヘッダーを取得する複数の方法、典型的なユースケース、よくあるつまづきと対策、そして実践的なサンプルコードを最新情報に基づいて丁寧に解説します。API開発者/利用者にとって必ず役に立つ内容です。
PHP cURL ヘッダー 取得の基本と必要性
まず最初に、PHPでcURLを使ってヘッダーを取得するとは何か、なぜ必要なのかを整理します。HTTPのレスポンスは主にヘッダー部分と本体(ボディ)部分から構成され、ステータスメッセージやコンテンツタイプ、認証情報、リダイレクト情報などの重要データがヘッダーにあります。この情報を取得できなければ、API通信の結果の判断や条件分岐に支障が出ます。例えば、取得したステータスコードで200以外ならエラー処理に入る、Content-Typeで処理を変える、Set-Cookieを読み取って次のリクエストに使う、などが典型的な用途です。ヘッダー取得は単なる付加情報ではなく、API通信を確実に扱うための土台と言えます。
HTTPレスポンスヘッダーとは何か
HTTPレスポンスヘッダーは、サーバーがクライアントに返す通信メタデータの集合です。ステータス行(例 HTTP/1.1 200 OK)から始まり、Content-Type、Content-Length、Set-Cookie、Cache-Controlなどが続きます。これらはクライアント側でリソースの形式や処理方法、キャッシュの挙動などを制御するための鍵になります。
API通信やデバッグでの活用例
外部APIを利用する際、ヘッダーを取得することで以下のようなメリットがあります。まずステータスコードで成功/失敗を判定することで無駄な処理を避けられます。次にContent-Typeに従ってデータ形式を解析できます。Set-Cookieで認証やセッション管理、またPaginationやリンクヘッダーで次ページ取得のロジックを構築できます。さらにレスポンスヘッダーによってキャッシュ制御やリダイレクト先を把握することも可能です。
cURL以外との比較:get_headers関数など
PHPにはget_headers関数があり、URLを指定するだけでサーバーのヘッダーを取得できます。しかしこの関数はGETリクエストに限られる点や、リダイレクトへの対応・詳細な設定が制約される場合がある点で、cURLの柔軟性には及びません。cURLを使えばHTTPメソッドの指定、SSL検証、HTTPヘッダー送信、ヘッダーのみ取得など細かい操作が可能になります。
cURLでヘッダー取得する具体的な方法
ここではPHPのcURLを用いてレスポンスヘッダーを取得する代表的な方法を実践的に説明します。CURLOPT_HEADERを使ってヘッダーを含めたレスポンスを取得する方法、CURLOPT_HEADERFUNCTIONでコールバックを使う方法、curl_getinfoでヘッダーサイズを計算して分離する方法などを取り上げます。それぞれにメリット・デメリットがあるため、目的や用途に応じて選択できるようになります。
CURLOPT_HEADERを使ってヘッダーも含めたレスポンス取得
この方法ではCURLOPT_HEADERオプションをtrueに設定することで、curl_execの返り値にヘッダー+ボディの両方が含まれます。例えばcurl_setopt($ch, CURLOPT_HEADER, true);を設定し、CURLOPT_RETURNTRANSFERも有効にすると、返ってきた文字列の先頭部分にヘッダーがあり、後半がボディです。単純明快ですが、ヘッダーとボディの分離処理が必要となる点がデメリットです。ヘッダーが複数のセクション(リダイレクトによる複数)を持つ場合、分離処理が若干複雑になります。
curl_getinfoとCURLINFO_HEADER_SIZEで分離する
CURLOPT_HEADERを有効にした場合、curl_getinfo関数を使ってCURLINFO_HEADER_SIZEを取得し、レスポンス文字列からヘッダー部分長を取り出すことができます。具体的にはsubstr関数で先頭からheader_sizeバイトをヘッダー、残りをボディとして切り分けます。これによりヘッダー/ボディが明確に分離されるため、bodyだけを扱いたいときやヘッダーを個別に解析したいときに非常に便利です。
CURLOPT_HEADERFUNCTIONを使って逐次ヘッダー取得
CURLOPT_HEADERFUNCTIONを使うと、レスポンスヘッダーが受信されるたびにコールバックが呼び出され、ヘッダー行を一行ずつ処理できます。これを使えば連想配列形式でヘッダーキーと値を分けて取得でき、解析がしやすくなります。流れとしては、コールバック関数内で正規表現などで行を分割し、ヘッダー配列に保存し、curl_exec後にその配列を参照します。大規模APIや非同期性を意識した処理で役立つ方法です。
実践的なサンプルコードとユースケース
ここでは具体的なサンプルを通じて、実際にPHPでcURLを使ってヘッダーを取得し、解析する流れをご紹介します。またAPI呼び出しとレスポンスを扱う現場でよくある要件に対応できるよう、認証ヘッダーの検出、JSON以外のContent-Typeの処理、リダイレクトの扱いなども含めます。
シンプルなゲットリクエストでヘッダーとボディを分離する例
以下はGETリクエストで外部APIからデータを取得し、ヘッダーとボディを分離して扱う例です。
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.example.com/data");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
$response = curl_exec($ch);
if(curl_errno($ch)){
// エラー処理
}
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header_string = substr($response, 0, $header_size);
$body = substr($response, $header_size);
curl_close($ch);
// ヘッダー文字列を配列に変換して使いやすくする処理を行う
この例では、curl_execで返された全レスポンスからcurl_getinfoでヘッダーの長さを取得し、substrで分割しています。header_stringをexplodeと正規表現で分解すれば、個別のヘッダーにアクセスできます。
POSTリクエスト+認証付きAPIでのヘッダー取得
多くのAPIではPOSTリクエストで認証ヘッダーを送る必要があります。この例では、認証トークンを送信し、レスポンスヘッダーを取得する流れを示します。
$data = ["key" => "value"];
$ch = curl_init("https://api.example.com/submit");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer TOKEN","Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
$response = curl_exec($ch);
if(curl_errno($ch)){
// エラー処理
}
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header_string = substr($response, 0, $header_size);
$body = substr($response, $header_size);
curl_close($ch);
// 認証用のSet-Cookieやその他のヘッダーを取り出して使う
逐次的にヘッダーを処理するコールバック方式の例
CURLOPT_HEADERFUNCTIONを使って、受信するヘッダー行をコールバック内で処理する例です。ヘッダーをキー/値で格納でき、解析が効率的です。
$headers = [];
$ch = curl_init("https://api.example.com/info");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Accept: application/json"]);
curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($ch, $header_line) use (&$headers) {
$matches = [];
if(preg_match('/^ {
$name = $matches[1];
$value = $matches[2];
$headers[$name][] = $value;
}
return strlen($header_line);
});
$body = curl_exec($ch);
if(curl_errno($ch)){
// エラー処理
}
curl_close($ch);
// $headers が連想配列で各ヘッダーを取得できる
落とし穴とよくあるトラブル対策
実際にPHPでcURLを使ってヘッダー取得を試すと、思い通りに動かないことがあります。ここでは典型的な問題点とその解決策を詳しく解説します。ステータス行だけ取得できない、header_sizeが0になる、リダイレクト先のヘッダーを取得できない、SSL証明書警告などのケースを扱います。しっかり対策を理解しておくと現場で困ることが減ります。
CURLINFO_HEADER_SIZEが0になる原因と対処
CURLOPT_HEADERをtrueに設定していない場合、curl_execの返り値にヘッダー部分が含まれず、header_sizeが0になることがあります。またcurl_execにエラーが発生しているがerrnoをチェックしていないため原因が不明になることが多いです。必ずcurl_setoptでCURLOPT_HEADERをtrueにし、curl_setoptでRETURNTRANSFERをtrueにし、curl_errnoで実行後のエラーを確認することが基本です。
リダイレクト対応時のヘッダー取得
curl_setoptでCURLOPT_FOLLOWLOCATIONをtrueにしたとき、リダイレクト先で新しいHTTPレスポンスが発生し、複数のヘッダーセクションが返されます。ヘッダー/ボディの分割処理ではheader_sizeが最終的なレスポンスヘッダーのサイズを示すため、explodeなどで複数セクションを分割するロジックが必要です。またリダイレクトチェーン全体のLocation情報を手動で追いたい場合はCURLOPT_HEADERFUNCTION方式で各セクションのヘッダーをキャプチャすると扱いやすくなります。
SSL検証と証明書エラーの回避
HTTPSでAPI呼び出しをする際、SSL証明書の検証設定が厳しい環境ではエラーが出ることがあります。curl_setoptでCURLOPT_SSL_VERIFYPEERやCURLOPT_SSL_VERIFYHOSTの設定を適切に行うことで回避できます。ただし本番環境では検証を無効にするのはセキュリティリスクになるため、信頼できる証明書を使うかCAバンドルを設定することが推奨されます。
大きなレスポンスやタイムアウトへの対応
ヘッダー取得自体は軽量でも、レスポンス本体が巨大だったりAPIが応答に時間がかかるケースがあります。CURLOPT_TIMEOUTやCURLOPT_CONNECTTIMEOUTでタイムアウトの設定を行い、CURLOPT_MAXREDIRSでリダイレクト数の上限を設けることで予期せぬ遅延を防げます。またCURLOPT_NOBODYを使って本体を取得せずヘッダーのみ取得する方法もあり、ヘッダーだけ確認したい用途には最適です。
curl_getinfoで取得できるヘッダー関連情報一覧
curl_getinfo関数は実際のヘッダー内容だけでなく通信に関するメタデータも取得でき、レスポンス処理やログ記録に非常に有用です。ここでは最新の定義に基づいたオプションと取得可能な情報を表形式でまとめます。この情報を知っておくと、通信のボトルネック発見や品質管理に役立ちます。
curl_getinfoの主なオプション
curl_getinfo関数には多くの定数オプションがあり、レスポンスヘッダーに関するメタ情報が含まれます。その中でも特によく使われるものには、CURLINFO_HTTP_CODE(ステータスコード)、CURLINFO_CONTENT_TYPE(Content-Typeヘッダー)、CURLINFO_HEADER_SIZE(ヘッダー部のサイズ)、CURLINFO_REDIRECT_COUNT(リダイレクト回数)などがあります。これらを使うことでヘッダー以外の関連情報も取得できます。
主な情報のまとめ比較表
| 情報の種類 | 定数名 | 用途 |
|---|---|---|
| ステータスコード | CURLINFO_HTTP_CODE | レスポンスが成功かどうかを判断する |
| コンテンツタイプ | CURLINFO_CONTENT_TYPE | レスポンスのデータ形式を把握する |
| ヘッダーサイズ | CURLINFO_HEADER_SIZE | レスポンスヘッダーと本体を分離するために使う |
| リダイレクト回数 | CURLINFO_REDIRECT_COUNT | 何回リダイレクトされたか把握する |
| 総通信時間 | CURLINFO_TOTAL_TIME | レスポンス取得にかかった時間を測定する |
curl_getinfo利用時の注意点
curl_getinfoで得られる情報はcurl_exec実行後のみ有効です。それ以前に呼び出しても正しい値を得られません。また、CURLOPT_HEADERを使ってヘッダー込みでレスポンスを取得していない場合、CURLINFO_HEADER_SIZEは意味を持たないことがあります。リダイレクトを追っている設定によって、取得できる情報が最終レスポンスに関するものかどうかを確認する必要があります。
応用とベストプラクティス
ここまでの基礎とサンプルを踏まえて、より実践的な場面でヘッダー取得をどう使うか、効率や保守性を高めるための設計上の考慮点を紹介します。認証ロジック、エラーハンドリング、テスト、共通ヘッダー処理など現場で重宝するパターンを含みます。
共通処理としてのヘッダー抽出関数化
ヘッダー取得+解析部分は重複しやすいため、関数としてまとめておくと保守が楽になります。例えば、レスポンス文字列からヘッダー文字列とボディを返す関数、正規表現で連想配列に変換する関数などを用意しておくと複数APIで使い回せます。これによりコードの重複が減り、バグの発生も抑えられます。
認証トークンやCookieの扱いに注意する
Set-Cookieヘッダーでセッションや認証情報をレスポンスヘッダーから得る必要があるケースがあります。同時に、クライアントリクエスト時のAuthorizationヘッダーや送信成形なども正確に行う必要があります。ヘッダーのキー名の大文字小文字、値の前後の空白、改行コードの取り扱いなど細部で動かないことがあるため、正規表現やtrimを使ってクリーンに処理することが重要です。
テストとデバッグで役立つ技法
開発段階でヘッダー取得が正しく行われていることを確認するため、以下のようなテスト方法があります。外部APIであればモックサーバーでHTTPレスポンスのヘッダーを意図的に設定してレスポンスを返すものを使う。また、curl_errorおよびcurl_errnoを使って実行エラーを取得し、ログに出すこと。さらにvar_exportやprint_rを使ってヘッダー配列を出力し、意図したキー値ペアになっているかを確認することが有効です。
まとめ
PHPとcURLを使って外部APIのレスポンスヘッダーを取得することは、通信結果を正しく扱う上で不可欠です。CURLOPT_HEADERでヘッダー込みのレスポンスを取得する手法、curl_getinfoでheader_sizeを使って分離する方法、CURLOPT_HEADERFUNCTIONで逐次処理する方法など、それぞれにメリットがあります。用途に合わせて最適な方法を選択することが重要です。
また、リダイレクト対応、SSL検証、タイムアウト設定などの「落とし穴」を事前に把握することで、本番環境での障害を防げます。共通処理としてヘッダー処理を関数化し、認証やCookie処理も正確に行うことで可読性と保守性が向上します。この記事で紹介したサンプルコードやベストプラクティスを応用すれば、外部APIのレスポンスをヘッダー含めて豊かに活用できるようになります。
コメント