wp_remote_get() などで取得した応答から、ステータスコード(200・404・429 など)を数値で取り出します。相手が 404 や 500 を返しても wp_remote_get() は WP_Error にはならないので、うまく取得できたかはこの関数で見ます。つながらなかったとき(WP_Error)は、空の文字列が返ります。
書き方
wp_remote_retrieve_response_code( array|WP_Error $response ): int|string
$response:wp_remote_get()・wp_remote_post()などの戻り値です。- 戻り値:ステータスコードの数値(
int)です。$responseがWP_Errorのときなどは、空の文字列('')です。
使い方の例
作業環境(WordPress 7.1.2)で試した結果を、コメントに書いています。
$response = wp_remote_get( home_url( '/' ) ); var_dump( wp_remote_retrieve_response_code( $response ) ); // int(200) echo wp_remote_retrieve_response_message( $response ); // OK // ないページ $response = wp_remote_get( home_url( '/no-such-page-xyz/' ) ); var_dump( is_wp_error( $response ) ); // bool(false)(404 でも WP_Error ではない) var_dump( wp_remote_retrieve_response_code( $response ) ); // int(404) echo wp_remote_retrieve_response_message( $response ); // Not Found // つながらない URL(今回は作業環境のサイトの :1 番のポート) $response = wp_remote_get( $unreachable_url, array( 'timeout' => 3 ) ); var_dump( is_wp_error( $response ) ); // bool(true) echo $response->get_error_code(); // http_request_failed var_dump( wp_remote_retrieve_response_code( $response ) ); // string(0) ""
コードで分けて、429 なら待つ秒数を返す
外の API を呼ぶときは、「つながらなかった」「取得できた」「呼びすぎ(429)」「それ以外の失敗」の順に分けておくと、あとで原因を追いやすくなります。429 と 503 のときは、Retry-After のヘッダーに入った秒数を、待つ時間として返します。
取得してコードで分ける関数
function my_fetch( $url ) {
$response = wp_remote_get( $url, array( 'timeout' => 10 ) );
if ( is_wp_error( $response ) ) {
return array( 'ok' => false, 'retry' => 60, 'error' => $response->get_error_code() );
}
$code = wp_remote_retrieve_response_code( $response );
if ( 200 === $code ) {
return array( 'ok' => true, 'body' => wp_remote_retrieve_body( $response ) );
}
if ( 429 === $code || 503 === $code ) {
$retry = wp_remote_retrieve_header( $response, 'Retry-After' );
return array( 'ok' => false, 'retry' => ctype_digit( $retry ) ? (int) $retry : 60 );
}
return array( 'ok' => false, 'retry' => 0, 'code' => $code );
}
429 は、pre_http_request のフィルターで「429 と Retry-After: 120 が返った」ことにして試しました。ほかは作業環境のサイトを実際に取得した結果です。
my_fetch( home_url( '/' ) ); // ok: true(body に本文) my_fetch( home_url( '/no-such-page-xyz/' ) ); // ok: false, retry: 0, code: 404 my_fetch( $busy_url ); // ok: false, retry: 120(429・Retry-After: 120) my_fetch( $unreachable_url ); // ok: false, retry: 60, error: http_request_failed
返ってきた retry が 0 より大きければ、その秒数のあとに取り直します。WordPress の中なら wp_schedule_single_event() で、あとから動く処理として予約する形が考えられますが、この部分は試していません。Retry-After が日時の形で返るときの扱いは、wp_remote_retrieve_header() のページの例を見てください。
気をつけること
- 先に is_wp_error() を見る:つながらなかったときは空の文字列が返るので、
$code >= 400のような比べ方では失敗に気づけません。試したところ、WP_Errorのときの'' >= 400はfalseになりました。 - 数値で比べる:戻り値は
intなので、'200' === $codeは合いません(試したところfalse)。200 === $codeのように数値で比べます。 - リダイレクトはたどったあとのコード:
wp_remote_get()はリダイレクトを自動でたどるので、最後に表示されたページのコードになります。今回検証したサイトの/wp-sitemap.xmlは、そのままでは 200、'redirection' => 0を付けると 302 でした。 - 説明の言葉(
Not Foundなど)がほしいときはwp_remote_retrieve_response_message()を使います。
関連する関数
- wp_remote_retrieve_header():取得した応答のヘッダーを読む
wp_remote_retrieve_response_message():ステータスコードの説明の言葉を読むwp_remote_retrieve_body():本文を取り出す- status_header():自分のページのステータスコードを決める
- add_query_arg():取得する URL にパラメーターを足す

