wp_remote_get()の結果はWP_Error、HTTPステータス、本文を分けて確認する
公開日: 執筆:佐藤
wp_remote_get()の返り値は、最初にis_wp_error()で通信処理の失敗を確認します。応答を受け取れた場合は、HTTPステータスを確認し、その条件を満たしたときだけ本文を使います。
WP_Errorではないことだけを成功条件にしてはいけません。接続先が404や500を返しても応答配列を受け取る場合があり、200でも期待する形式の本文とは限りません。
通信、HTTP応答、本文は三つの段階である
WordPress 3.8のHTTP APIでは、wp_remote_get()は成功時の応答配列または失敗時のWP_Errorを返します。
| 段階 | 確認方法 | 分かること | まだ分からないこと |
|---|---|---|---|
| 通信処理 | is_wp_error() |
WordPressが要求を完了できたか | 接続先が要求を受理したか |
| HTTP応答 | wp_remote_retrieve_response_code() |
200、404、500などの状態 | 本文が期待するデータか |
| 本文 | wp_remote_retrieve_body()と形式検査 |
受け取った内容 | その内容が業務上正しいか |
DNS、接続、SSL、タイムアウトなどの問題は、WP_Errorとして返ることがあります。HTTPステータスは、接続先から応答が返ったあとの結果です。本文の形式と値は、さらに別の検査です。
WP_Errorを最初に確認する
固定した外部URLから情報を取得する基本形は、次のようになります。
$response = wp_remote_get(
'https://api.example.com/status',
array(
'timeout' => 10,
)
);
if ( is_wp_error( $response ) ) {
$error_code = $response->get_error_code();
$error_message = $response->get_error_message();
return;
}
WP_Errorには、エラーコードとメッセージがあります。利用者へ内部情報をそのまま表示せず、管理用の記録へ残し、公開画面では代替表示や再試行案内を出します。
wp_remote_retrieve_response_code()とwp_remote_retrieve_body()は、WP_Errorを渡すと空文字列を返します。先にエラーを分けないと、通信失敗、応答コードの欠落、空の本文を同じ空文字列として扱うことになります。
HTTPステータスを本文より先に確認する
通信処理が完了したら、HTTPステータスを取り出します。
$status = (int) wp_remote_retrieve_response_code( $response );
if ( 200 !== $status ) {
return;
}
$body = wp_remote_retrieve_body( $response );
この例は、接続先の仕様で200だけを受理する場合です。201、204など、ほかの成功ステータスを使うサービスでは、その仕様に合わせて許可する値を決めます。
404は取得対象がないこと、500は接続先の処理失敗を示しますが、どちらもWordPress側の通信機能が失敗したという意味ではありません。is_wp_error()だけで分岐すると、エラーページのHTMLを正しいデータとして保存する危険があります。
反対に、404や500の本文には診断用の情報が入る場合があります。業務データとしては使わず、必要な範囲だけ管理記録へ残します。認証情報、個人情報、接続先が返した全文を無条件にログへ書かないでください。
200でも本文の形式を確認する
HTTP 200は、要求に対して成功応答が返ったことを示します。本文が空でないこと、期待する形式であること、必要な項目があることまでは保証しません。
接続先ごとに、次の条件を決めます。
- 受理するHTTPステータス
- 空の本文を許すか
- HTML、XML、JSONなど期待する形式
- 必須項目と値の範囲
- データが不完全な場合の代替表示
- 再試行する条件と回数
説明用の仮例では、在庫APIから200とHTMLのメンテナンス画面が返ることがあります。HTTP上の成功だけで、そのHTMLを在庫データとして保存してはいけません。形式と必須項目を確認し、失敗した取得結果で保存済みデータを上書きしない判断が必要です。
本文を公開画面へ出す場合も、接続先を信用してそのままHTMLとして出力しません。用途に応じてデータを検証し、文字列なら適切にエスケープします。
利用者が指定するURLにはwp_safe_remote_get()を検討する
取得先がテーマやプラグインで固定され、管理者が確認したURLなら、wp_remote_get()で要求できます。一方、フォームや外部データから任意のURLを受け取る場合は、内部ネットワークへの要求や危険なリダイレクトを防ぐ必要があります。
WordPress 3.8のwp_safe_remote_get()は、reject_unsafe_urlsを有効にして要求します。利用者が指定できるURLでは、この関数を検討し、許可するスキーム、ホスト、用途も別に制限します。
安全用の関数を使っても、取得した本文が正しい業務データになるわけではありません。URLの安全確認と、HTTPステータス、本文の検証は別々に行います。
失敗記録は段階を残す
外部取得を保守するときは、「APIエラー」と一語で記録せず、失敗した段階を残します。
| 記録項目 | 例 |
|---|---|
| 取得先 | 認証情報を除いたホストとパス |
| 通信結果 | WP_Errorのコード、必要な範囲のメッセージ |
| HTTP結果 | ステータスコード |
| 本文検査 | 空、形式違い、必須項目なしなど |
| 処理判断 | 既存データ維持、代替表示、再試行 |
| 管理情報 | 実行日時、担当、設定変更の有無 |
制作会社へ実装を委託しても、取得先、認証情報の管理者、失敗時に残すデータ、再試行条件はサイト側で決めます。接続先の障害で、自社サイトの公開画面や保存済みデータまで壊さない構成にします。
最初の一手は、既存のwp_remote_get()を一つ選び、is_wp_error()、HTTPステータス、本文検査の三段階があるかを確認することです。どれか一つしかなければ、保存や表示より前に分岐を追加してください。
関連記事

