かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

PHP file_get_contents()でAPIを叩いた時のエラーハンドリングしたい

URLを指定してGETでデータが返ってくるようなWebAPIを叩くのにfile_get_contents()を使ってみました。(もっと良い方法があれば教えて下さい。)
で、APIからデータは取得できたのですが、例えばAPI叩きすぎとかでAPIからエラーを返されることがあります。
その際に、そのままだとWarningが表示されてしまい、その後の処理でエラーになってしまったりするのでエラーハンドリングをしたいと思います。

$http_response_headerでレスポンスのステータスコードをチェックして判別する

file_get_contents ()HTTP ラッパーを使うと $http_response_header にレスポンスヘッダが自動的にセットされます。ステータス行は必ず 1 行目なので $http_response_header[0] を確認すればステータスコードが分かります。

PHP の file_get_contents でステータスコードを取得する

<?php
class MyAPI {
  private $apiURL = 'https://URL';

  public function getData($params = '') {
    $data = null;
    // エラーの場合も取得する設定にする
    $context = stream_context_create(array(
      'http' => array('ignore_errors' => true)
     ));
     // WebAPIを叩く 
     $res = file_get_contents($this->apiURL . $params, false, $context);
     // ステータスコードが200かどうかチェック
    $is_seccess = strpos($http_response_header[0], '200');
    if( $is_seccess === false ) {
      // ステータスコードが200以外 => エラー
      throw new Exception("API ERROR: {$http_response_header[0]}");
    } else {
     // SUCCESS  データ取得時の処理
     $data = json_decode($res, true);
    }
  }
  return $data;
}

ステータスコードごとに処理を変える場合は、preg_match()でステータス($http_response_header[0])からステータスコードを取得して処理分けすると良さそうです。

<?php 
class MyAPI {
 /* 略 */
 public function getData($params = '') {
    /* 略 */
    // $http_response_header からステータスコードを取得する
    preg_match('/HTTP\/1\.[0|1|x] ([0-9]{3})/', $http_response_header[0], $matches);
    $status_code = $matches[1];
    switch( $status_code ) {
      case '404':
        // 404の時の処理
      break;
      case '403':
        // 404の時の処理
      break;
      case '200'
        // 200の時の処理
      break;
      default:
      break;
    }
    /* 略 */
  }
}

使い方のサンプル

<?php 
$api = new MyAPI();

try {
  // WebAPIからデータを取得
  $apiData = $api->getData();
} catch (Exception $e) {
  // 失敗した場合はログに記録
  error_log($e->getMessage() . "\n", 3, $logfile);
  exit;
}

[参考]

くまみこ 公式アンソロジー (MFC)

くまみこ 公式アンソロジー (MFC)