【PHP8.x】CURLINFO_RETRY_AFTER定数の使い方
CURLINFO_RETRY_AFTER定数の使い方について、初心者にもわかりやすく解説します。
基本的な使い方
CURLINFO_RETRY_AFTER定数は、PHPのcURL拡張機能において、HTTPリクエストに対するサーバーからのレスポンスに含まれるRetry-Afterヘッダの情報を取得するために使用される定数です。この定数は、主にcurl_getinfo()関数と組み合わせて利用されます。
ウェブサーバーは、一時的な過負荷やメンテナンスなどの理由で、クライアントからのリクエストに対して「しばらくしてから再試行してください」という指示を出すことがあります。この指示は、HTTPステータスコード503 Service Unavailableなどと共に、Retry-Afterヘッダフィールドに具体的な待機時間を秒数、または特定の日付・時刻で指定することで行われます。
CURLINFO_RETRY_AFTER定数をcurl_getinfo()関数に渡すことで、プログラムはこのRetry-Afterヘッダに指定された値を数値(秒数)として取得できます。これにより、開発者はサーバーの指示に従って適切な時間待機し、不必要な再試行を避けてサーバーへの負荷を軽減するような、より賢明なクライアント側の再試行ロジックを実装することが可能になります。もしレスポンスにRetry-Afterヘッダが存在しない場合や、その値が秒数として解析できない形式である場合は、通常0が返されます。この定数は、ネットワーク通信において堅牢性と効率性を高める上で役立つ情報を提供します。
構文(syntax)
1CURLINFO_RETRY_AFTER;
引数(parameters)
引数なし
引数はありません
戻り値(return)
float
CURLINFO_RETRY_AFTERは、リクエストが失敗した場合に、次にリクエストを再試行するまでの推奨秒数を浮動小数点数で返します。
サンプルコード
PHP cURLでHTTPコードとリトライ情報を取得する
1<?php 2 3/** 4 * 指定されたURLにcURLリクエストを送信し、HTTPステータスコードと 5 * 必要に応じてRetry-After情報を取得・表示します。 6 * 7 * @param string $url リクエストを送信するURL 8 * @return void 9 */ 10function fetchServiceStatusAndRetryInfo(string $url): void 11{ 12 // cURLセッションを初期化します。 13 $ch = curl_init($url); 14 15 // レスポンスの内容を文字列として取得する設定をします。 16 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 17 18 // cURLリクエストを実行します。 19 $response = curl_exec($ch); 20 21 // cURL実行中にエラーが発生した場合の処理です。 22 if (curl_errno($ch)) { 23 echo 'cURL エラーが発生しました: ' . curl_error($ch) . PHP_EOL; 24 curl_close($ch); 25 return; 26 } 27 28 // CURLINFO_RESPONSE_CODE を使用して、HTTPステータスコード(例: 200, 404, 503)を取得します。 29 $httpStatusCode = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); 30 echo "URL: " . $url . PHP_EOL; 31 echo "HTTP ステータスコード: " . $httpStatusCode . PHP_EOL; 32 33 // ステータスコードが503 (Service Unavailable) の場合 34 if ($httpStatusCode === 503) { 35 // CURLINFO_RETRY_AFTER は、HTTP 503レスポンスに含まれる可能性のある 36 // "Retry-After"ヘッダーの値(再試行までの秒数)を取得します。 37 // このヘッダーが存在しない場合、通常 0.0 が返されます。 38 $retryAfterSeconds = curl_getinfo($ch, CURLINFO_RETRY_AFTER); 39 40 if ($retryAfterSeconds > 0) { 41 echo "サービスは一時的に利用できません。 " . $retryAfterSeconds . " 秒後に再試行してください。" . PHP_EOL; 42 } else { 43 echo "サービスは一時的に利用できませんが、再試行時間は指定されていません。" . PHP_EOL; 44 } 45 } elseif ($httpStatusCode === 200) { 46 echo "サービスは正常に動作しています。" . PHP_EOL; 47 } else { 48 echo "その他のステータスコードです。サービスの状態を確認してください。" . PHP_EOL; 49 } 50 51 // cURLセッションを閉じ、リソースを解放します。 52 curl_close($ch); 53 echo PHP_EOL; // 見やすくするための改行 54} 55 56// --- サンプルコードの実行例 --- 57 58// 1. 正常なHTTPステータスコード (200 OK) の例 59// httpbin.orgはテスト用のHTTPリクエスト/レスポンスサービスです。 60echo "--- 正常なサービスへのリクエスト (200 OK) ---" . PHP_EOL; 61fetchServiceStatusAndRetryInfo('https://httpbin.org/status/200'); 62 63// 2. ページが見つからないHTTPステータスコード (404 Not Found) の例 64echo "--- 存在しないページへのリクエスト (404 Not Found) ---" . PHP_EOL; 65fetchServiceStatusAndRetryInfo('https://httpbin.org/status/404'); 66 67// 3. サービスが一時的に利用できないHTTPステータスコード (503 Service Unavailable) の例 68// httpbin.orgはデフォルトでRetry-Afterヘッダーを返さないため、 69// CURLINFO_RETRY_AFTERは0.0を返す可能性が高いです。 70echo "--- 503エラーのシミュレーション (Retry-Afterヘッダーなし) ---" . PHP_EOL; 71fetchServiceStatusAndRetryInfo('https://httpbin.org/status/503'); 72 73// 備考: CURLINFO_RETRY_AFTERが意味のある値(0.0より大きい値)を返すには、 74// 実際にHTTP 503レスポンスと "Retry-After" ヘッダーを返すサーバーが必要です。 75// ローカルでテストサーバーを構築するか、そのようなヘッダーを返す公開サービスがあれば試してみてください。 76// 例: header('HTTP/1.1 503 Service Unavailable'); header('Retry-After: 30'); を返すPHPスクリプトなど。
このPHPコードは、指定されたURLに対してcURLライブラリを用いてHTTPリクエストを送信し、その結果からHTTPステータスコードや、場合によってはサービス再開までの推奨時間を取得・表示するfetchServiceStatusAndRetryInfo関数を定義しています。関数は引数としてリクエスト対象のURL(文字列)を受け取り、処理結果を画面に出力するだけで、具体的な戻り値はありません(void)。
まず、curl_initでcURLセッションを初期化し、CURLOPT_RETURNTRANSFERオプションでレスポンスを文字列として取得する設定を行います。その後、curl_execでリクエストを実行し、エラーが発生しないことを確認します。リクエストが成功した場合、curl_getinfo関数とCURLINFO_RESPONSE_CODE定数を使用して、HTTPステータスコード(例: 200 OK, 404 Not Found, 503 Service Unavailable)を取得し表示します。
特にステータスコードが503(Service Unavailable)の場合、curl_getinfo関数にCURLINFO_RETRY_AFTER定数を指定することで、サーバーから提供される可能性のある「Retry-After」ヘッダーの値、つまり再試行が推奨されるまでの秒数(float型)を取得します。このヘッダーが存在しない場合は通常0.0が返されるため、値が0より大きい場合に具体的な再試行メッセージを表示します。最後にcurl_closeでcURLセッションを閉じ、リソースを解放します。この機能は、外部サービスの稼働状況を確認し、一時的な障害時に適切な対応を判断する際に役立ちます。
CURLINFO_RETRY_AFTERは、HTTP 503レスポンスに「Retry-After」ヘッダーが含まれる場合に、再試行までの秒数を数値で返します。このヘッダーがない場合や他のステータスコードでは0.0を返すため、値が0より大きいかで判断が必要です。情報を取得するcurl_getinfoは、curl_execでリクエストを実行し、応答を得た後に呼び出す必要があります。cURLセッションは、通信エラーの確認をcurl_errnoで行った後、最終的にcurl_closeで必ず閉じ、リソースを適切に解放するように心がけましょう。これらの手順を守ることで、安定したネットワーク通信処理を実装できます。
PHP cURLでHTTPコードとRetry-Afterを取得する
1<?php 2 3/** 4 * 指定されたURLにHTTPリクエストを送信し、HTTPステータスコードと 5 * 必要に応じてRetry-Afterヘッダーの情報を取得します。 6 * 7 * システムエンジニアを目指す初心者の方へ: 8 * この関数は、ウェブサイトへの接続(HTTPリクエスト)を行い、 9 * その結果としてサーバーから返される「HTTPステータスコード」(例えば、成功なら200、ページが見つからなければ404) 10 * や、「サーバーが一時的に利用できない場合(503エラー)」に、 11 * 「何秒後に再試行すべきか(Retry-After)」という情報を取得する方法を示しています。 12 * 13 * @param string $url リクエストを送信するURL。例: 'https://www.example.com' 14 * @return array 取得した情報を含む連想配列。エラー発生時は'error'キーが含まれます。 15 */ 16function getUrlHttpResponseInfo(string $url): array 17{ 18 // cURLセッションを初期化します。cURLはPHPでHTTP通信を行うための拡張機能です。 19 $ch = curl_init(); 20 21 // cURLのオプションを設定します。 22 // CURLOPT_URL: リクエストを送信するURLを指定します。 23 curl_setopt($ch, CURLOPT_URL, $url); 24 // CURLOPT_RETURNTRANSFER: curl_exec()の戻り値として、取得したデータを文字列で返すようにします。 25 // これを設定しないと、取得したデータが直接出力されます。 26 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 27 // CURLOPT_HEADER: レスポンスヘッダーをボディと一緒に出力しないようにします。 28 // ヘッダー情報はcurl_getinfo()で別途取得します。 29 curl_setopt($ch, CURLOPT_HEADER, false); 30 31 // HTTPリクエストを実行し、サーバーからのレスポンスボディを取得します。 32 $responseBody = curl_exec($ch); 33 34 // cURLの実行中にエラーが発生したかチェックします。 35 if (curl_errno($ch)) { 36 $error = curl_error($ch); 37 curl_close($ch); // エラーが発生した場合もセッションを閉じます。 38 return ['error' => "cURLエラーが発生しました: {$error}"]; 39 } 40 41 // HTTPステータスコードを取得します。 42 // CURLINFO_HTTP_CODEは、ウェブサーバーが返した200, 404, 503などのコードを返します。 43 $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); 44 45 $result = [ 46 'url' => $url, 47 'http_code' => $httpCode, 48 'response_body_length' => strlen($responseBody) // レスポンスボディの長さを表示 49 ]; 50 51 // HTTPステータスコードが503 (Service Unavailable) の場合、 52 // サーバーが「一時的にサービスを提供できない」と伝えている状態です。 53 // この場合、Retry-Afterヘッダーで「何秒後に再試行してほしいか」が伝えられることがあります。 54 if ($httpCode === 503) { 55 // CURLINFO_RETRY_AFTERは、HTTPレスポンスのRetry-Afterヘッダーの値を秒数(float型)で取得します。 56 $retryAfterSeconds = curl_getinfo($ch, CURLINFO_RETRY_AFTER); 57 58 if ($retryAfterSeconds > 0) { 59 $result['retry_after_seconds'] = $retryAfterSeconds; 60 $result['message'] = "サーバーは一時的に利用できません。{$retryAfterSeconds}秒後に再試行してください。"; 61 } else { 62 $result['message'] = "サーバーは一時的に利用できませんが、再試行までの推奨時間は指定されていません。"; 63 } 64 } else { 65 $result['message'] = "HTTPステータスコード: {$httpCode} で応答しました。"; 66 if ($httpCode === 200) { 67 $result['message'] .= " (成功)"; 68 } elseif ($httpCode === 404) { 69 $result['message'] .= " (ページが見つかりません)"; 70 } 71 } 72 73 // cURLセッションを閉じ、リソースを解放します。 74 curl_close($ch); 75 76 return $result; 77} 78 79// --- 関数利用例 --- 80 81echo "--- 正常なウェブサイトへのアクセス例 ---\n"; 82// 存在するURLへのリクエスト(通常は200 OK) 83$info = getUrlHttpResponseInfo('https://www.php.net'); 84if (isset($info['error'])) { 85 echo $info['error'] . "\n"; 86} else { 87 echo "アクセス先: " . $info['url'] . "\n"; 88 echo "HTTPステータスコード: " . $info['http_code'] . "\n"; 89 echo "メッセージ: " . $info['message'] . "\n"; 90 echo "レスポンスボディのサイズ: " . $info['response_body_length'] . "バイト\n"; 91} 92echo "\n"; 93 94echo "--- 503 Service Unavailable と Retry-After の例 ---\n"; 95// このURLは、意図的に503エラーとRetry-Afterヘッダーを返すように設定されたテストサービスです。 96// 実際のサーバーが過負荷の場合などに似た応答をシミュレートできます。 97$infoRetry = getUrlHttpResponseInfo('https://httpstat.us/503?retry-after=15'); // 15秒後に再試行を推奨 98if (isset($infoRetry['error'])) { 99 echo $infoRetry['error'] . "\n"; 100} else { 101 echo "アクセス先: " . $infoRetry['url'] . "\n"; 102 echo "HTTPステータスコード: " . $infoRetry['http_code'] . "\n"; 103 echo "メッセージ: " . $infoRetry['message'] . "\n"; 104 if (isset($infoRetry['retry_after_seconds'])) { 105 echo "推奨再試行時間 (秒): " . $infoRetry['retry_after_seconds'] . "秒\n"; 106 } 107} 108echo "\n"; 109 110echo "--- 存在しないページへのアクセス例 ---\n"; 111// 存在しないURLへのリクエスト(通常は404 Not Found) 112$infoNotFound = getUrlHttpResponseInfo('https://www.php.net/non-existent-page-xyz'); 113if (isset($infoNotFound['error'])) { 114 echo $infoNotFound['error'] . "\n"; 115} else { 116 echo "アクセス先: " . $infoNotFound['url'] . "\n"; 117 echo "HTTPステータスコード: " . $infoNotFound['http_code'] . "\n"; 118 echo "メッセージ: " . $infoNotFound['message'] . "\n"; 119} 120echo "\n"; 121 122?>
このPHPサンプルコードは、指定されたURLへHTTPリクエストを送信し、その応答情報、特にHTTPステータスコードと、必要に応じてHTTPヘッダーのRetry-Afterの情報を取得する方法を示しています。getUrlHttpResponseInfo関数は、curl_init()でcURLセッションを開始し、curl_setopt()でリクエスト対象のURLや応答の取得方法を設定します。リクエストがcurl_exec()で実行された後、curl_getinfo()関数を用いて、ウェブサーバーが返した「HTTPステータスコード」(例えば200 OK、404 Not Foundなど)をCURLINFO_HTTP_CODE定数で取得します。特にHTTPステータスコードが503(Service Unavailable)の場合、サーバーは一時的にサービスを提供できないことを示しており、この際に「何秒後に再試行すべきか」をRetry-Afterヘッダーで伝えることがあります。curl_getinfo()は、CURLINFO_RETRY_AFTER定数を使用することで、このRetry-Afterヘッダーの値を秒数としてfloat型で取得できます。この関数は、引数としてリクエスト対象のURL(文字列)を受け取り、結果としてHTTPステータスコードやRetry-Afterの値などを含む連想配列を返します。これにより、ウェブサービスが一時的に利用できない状況での適切な再試行タイミングを判断するのに役立ちます。
このコードは、ウェブサイトへのHTTPリクエストを行うcURLの基本的な使い方とエラー処理を学ぶ上で大変役立ちます。cURLセッションはcurl_init()で初期化したら、処理の最後に必ずcurl_close()でリソースを解放する習慣をつけましょう。また、curl_exec()による通信後には、常にcurl_errno()でエラーの有無を確認し、問題が発生した場合に備えた適切なエラーハンドリングを実装することが重要です。CURLINFO_HTTP_CODEはサーバーの応答結果を判断する基本的な情報であり、CURLINFO_RETRY_AFTERは主にHTTPステータスコード503のように再試行を推奨される特定の状況下で利用される情報であることを理解しておくと良いでしょう。外部サービスとの連携では、ネットワーク状況やサーバーの応答に左右されるため、実際の運用ではより堅牢なエラー処理やタイムアウト設定も検討してください。