wp_remote_retrieve_header():取得した応答のヘッダーを読む(WordPress)

WordPress

wp_remote_get() などで取得した応答から、ヘッダー(Content-Type・Retry-After など)の値を 1 つ取り出します。ヘッダーの名前は大文字・小文字を区別しないので、'Content-Type' でも 'content-type' でも同じ値が返ります。そのヘッダーがないときや、取得に失敗して WP_Error が返ったときは、空の文字列になります。

書き方

wp_remote_retrieve_header( array|WP_Error $response, string $header ): array|string
  • $response:wp_remote_get()・wp_remote_post() などの戻り値です。
  • $header:読みたいヘッダーの名前です。大文字・小文字は区別しません。
  • 戻り値:ヘッダーの値の文字列です。ないときと、$response が WP_Error のときは空の文字列('')です。同じ名前のヘッダーがいくつも返ったときは配列になります。

使い方の例

作業環境(WordPress 7.1.2)で試した結果を、コメントに書いています。

$response = wp_remote_get( home_url( '/' ) );

if ( is_wp_error( $response ) ) {
    return; // 取得に失敗した(下の「気をつけること」を見てください)
}

echo wp_remote_retrieve_header( $response, 'Content-Type' ); // text/html; charset=UTF-8
echo wp_remote_retrieve_header( $response, 'content-type' ); // text/html; charset=UTF-8(同じ値)
echo wp_remote_retrieve_header( $response, 'CONTENT-TYPE' ); // text/html; charset=UTF-8(同じ値)

// ないヘッダーは空の文字列
var_dump( wp_remote_retrieve_header( $response, 'Retry-After' ) ); // string(0) ""

リダイレクトの行き先(Location)を見たいときは、redirection を 0 にして、自動でたどらないようにします。たどると、行き先のページの応答になるためです。今回検証したサイトでは、/wp-sitemap.xml が /sitemap.xml へ 302 で移る設定になっていました。

$response = wp_remote_get( home_url( '/wp-sitemap.xml' ), array( 'redirection' => 0 ) );
echo wp_remote_retrieve_response_code( $response );      // 302
echo wp_remote_retrieve_header( $response, 'location' ); // (サイトのトップ)/sitemap.xml

// 0 にしないと、行き先の応答になる
$response = wp_remote_get( home_url( '/wp-sitemap.xml' ) );
echo wp_remote_retrieve_response_code( $response );          // 200
echo wp_remote_retrieve_header( $response, 'content-type' ); // text/xml; charset=UTF-8

429 のときに、何秒待てばよいかを Retry-After から決める

相手の API が「呼びすぎ」の 429(や 503)を返すときは、Retry-After のヘッダーに、待ってほしい秒数か、取り直してよい日時が入っていることがあります。下の関数は、待つ秒数を返すところまでを行います。待ったあとに取り直す部分は、呼び出す側で決めます。

待つ秒数を返す関数
function my_retry_wait_seconds( $response, $default = 60 ) {
    if ( is_wp_error( $response ) ) {
        return $default; // つながらなかった
    }
    $code = wp_remote_retrieve_response_code( $response );
    if ( 429 !== $code && 503 !== $code ) {
        return 0; // 待たなくてよい
    }
    $retry = wp_remote_retrieve_header( $response, 'Retry-After' );
    if ( '' === $retry ) {
        return $default; // Retry-After がない
    }
    if ( ctype_digit( $retry ) ) {
        return (int) $retry; // 秒数の形(例:120)
    }
    $time = strtotime( $retry ); // 日時の形(例:Fri, 23 Oct 2026 17:12:33 GMT)
    if ( false === $time ) {
        return $default;
    }
    return max( 0, $time - time() );
}

作業環境には 429 を返すページがないので、pre_http_request のフィルターで「429 と Retry-After が返った」ことにして試しました。結果は次のとおりです。

// Retry-After: 120 の 429
echo my_retry_wait_seconds( $response ); // 120

// Retry-After: (5 分後の日時)の 429
echo my_retry_wait_seconds( $response ); // 300

// Retry-After がない 429
echo my_retry_wait_seconds( $response ); // 60(決めておいた値)

// ふつうに取得できた 200
echo my_retry_wait_seconds( $response ); // 0

// つながらなかった(WP_Error)
echo my_retry_wait_seconds( $response ); // 60

気をつけること

  • 先に is_wp_error() を見る:取得に失敗したときも、この関数はエラーを出さずに空の文字列を返すだけです。作業環境のサイトの、つながらないポート(:1)を取得してみると、WP_Error(http_request_failed・cURL error 7)が返り、ヘッダーは '' になりました。そのため、「ヘッダーがない」と「取得できなかった」は、is_wp_error() で分けます。
  • 404 や 429 は WP_Error にならない:相手が 404 や 429 を返しても、取得そのものは成功した扱いです。うまく取得できたかは wp_remote_retrieve_response_code() で見ます。
  • 値は文字列:Retry-After: 120 は '120' の文字列で返るので、計算に使うときは (int) にします。日時の形で返ることもあるので、数字だけかを先に確認します。
  • 配列が返ることがある:同じ名前のヘッダーがいくつも返ったときは配列になります(この形は試していません)。文字列のつもりで扱うと困るときは、is_array() で確認します。
  • ヘッダーをまとめて見たいときは wp_remote_retrieve_headers() を使います。戻り値は配列のように読めるオブジェクトで、ここでも名前の大文字・小文字は区別しません。

関連する関数

  • wp_remote_retrieve_response_code():取得した応答のステータスコードを読む
  • wp_remote_retrieve_headers():ヘッダーをまとめて取り出す
  • wp_remote_retrieve_body():本文を取り出す
  • home_url():サイトのトップからの URL を作る
  • status_header():自分のページで 429 などを返す

参考

逆引きリファレンスの一覧へ