LaravelでInstagramに投稿された写真を全取得してみた

最近、LaravelでInstagram APIを使うことがあったのでメモ。
 
Instagram APIではユーザーの投稿したメディアを取得することができるのだが、一度のリクエストで最大20件までしか取得することができない。

そのため20件以上のメディアを取得したい場合は、ページングして取得するプログラムを自分で組まなくてはいけなかった。

それをやってみた。 

(追記)
今回の記事はInstagramでOAuth認証が前提となるので、先にOAuth認証をやってから、実践してみてください！
参考記事→[LaravelでInstagramログインをやってみた](http://qiita.com/daiki_44/items/6d01029cd3a7e7111c9a?get_all_media)

## 環境
- PHP5.6
- Laravel5.2

## 叩くURL
- https://api.instagram.com/v1/users/[取得するInstagrammerのID]/media/recent/

## 付与できるパラメータ
- ACCESS_TOKEN(必須)→OAuth認証をして取得したtoken
- MAX_ID→指定された場合、このIDより後に投稿されたメディアを取得
- MIN_ID→指定された場合、このIDより前に投稿されたメディアを取得
- COUNT→指定された場合、取得件数を指定

## ソースコード
```php:getInstagramMedia.php
/**
  * @params string $instagram_id OAuth認証後、取得されたInstagramID
  * @params string $access_token OAuth認証後、取得されたaccess_token
  */

public function getMediaList($instagram_id, $access_token) {

  # 1回目のloopを回すため20に
  $count = 20;
  $max_id = null;
  $data = array();
  $status = true;

  while ($count == 20) {
    $media_api_url = 'https://api.instagram.com/v1/users/' . $instagram_id . '/media/recent?access_token=' . $access_token. '&count=20';

    # max_idがセットされていたら、パラメータに付与
    # ここでページングのような感じになる
    if (!is_null($max_id)) {
      $media_api_url .= '&max_id=' . $max_id;
    }

    $context = stream_context_create(array('http' => array('ignore_errors' => true)));
    $json = file_get_contents($media_api_url, false, $context);

    $status_code = $this->getStatusCode($http_response_header[0]);
    if ($status_code == 200) {
      # decodeした配列をpush
      $media_list = json_decode($json);
      array_push($data, $media_list->data);

      # 20投稿取れたらまだ次ページがあるのでループを続ける
      $count = count($media_list->data);
      if ($count == 20) {
        $max_id = $media_list->data[$count - 1]->id;
      }
    } else {
      # 1度でもstatus_codeが200以外だったら、何もしないのでfalseで返す
      $status = false;
      break;
    }
  }

  if ($status) {
    return $data;
  }

  return false;
}

 

/**
  * file_get_contets後、status_codeを取得する
  */
public function getStatusCode($http_response_header) {

  preg_match('/HTTP\/1\.[0|1|x] ([0-9]{3})/', $http_response_header, $matches);
  $status_code = $matches[1];

  return $status_code;
}
```

## レスポンス
上記のソースコードでJSONが返却されるので、後はループしてメディア情報を取得していけばOK。

レスポンスはこんな感じ。

```json:response.json
array(1) {
  # ページ番号
  [0]=>
  # mediaの配列
  array(2) {
    # 1つ目のmedia
    [0]=>
    object(stdClass)#159 (15) {
      # media id
      ["id"]=>
      string(28) "283029249630288979_223689238"
      ["user"]=>
      object(stdClass)#160 (4) {
        ["id"]=>
        string(9) "223689238"
        ["full_name"]=>
        string(15) "Daiki Sekiguchi"
        ["profile_picture"]=>
        string(105) "https://scontent.cdninstagram.com/t51.2885-19/s150x150/16789727_236142133514690_5385687353354354688_a.jpg"
        ["username"]=>
        string(15) "daiki.sekiguchi"
      }
      # 投稿写真。サムネとか低画質とか色々な種類があるので、必要なものを適宜使用。
      ["images"]=>
      object(stdClass)#161 (3) {
        ["thumbnail"]=>
        object(stdClass)#162 (3) {
          ["width"]=>
          int(150)
          ["height"]=>
          int(150)
          ["url"]=>
          string(101) "https://scontent.cdninstagram.com/t51.2885-15/s150x150/e15/11230350_1098596466824017_1845423183_n.jpg"
        }
        ["low_resolution"]=>
        object(stdClass)#163 (3) {
          ["width"]=>
          int(320)
          ["height"]=>
          int(320)
          ["url"]=>
          string(101) "https://scontent.cdninstagram.com/t51.2885-15/s320x320/e15/11230350_1098596466824017_1845423183_n.jpg"
        }
        ["standard_resolution"]=>
        object(stdClass)#164 (3) {
          ["width"]=>
          int(612)
          ["height"]=>
          int(612)
          ["url"]=>
          string(92) "https://scontent.cdninstagram.com/t51.2885-15/e15/11230350_1098596466824017_1845423183_n.jpg"
        }
      }
      ["created_time"]=>
      string(10) "1347959737"
      ["caption"]=>
      NULL
      ["user_has_liked"]=>
      bool(false)
      ["likes"]=>
      object(stdClass)#165 (1) {
        ["count"]=>
        int(5)
      }
      ["tags"]=>
      array(0) {
      }
      ["filter"]=>
      string(5) "Amaro"
      ["comments"]=>
      object(stdClass)#166 (1) {
        ["count"]=>
        int(0)
      }
      ["type"]=>
      string(5) "image"
      ["link"]=>
      string(39) "https://www.instagram.com/p/PthZpdQjxT/"
      ["location"]=>
      NULL
      ["attribution"]=>
      NULL
      ["users_in_photo"]=>
      array(0) {
      }
    }
    # 2件目の投稿
    [1]=>
    object(stdClass)#167 (15) {
      ["id"]=>
      string(28) "282904296255798780_223689238"
続く...
```
## 公式Doc
- [Instagram Developer Documentation](https://www.instagram.com/developer/endpoints/users/#get_users_media_recent)

## 所感
これ、あんまりLaravel関係なくね！？
って読み返して思いました。。。

本来はLaravelでInstagramのOAuth認証をしてから、メディア取得に入ります。
今回はLaravelの記述があまりできていませんでしたが、次回はLaravelでInstagramのOAuth認証とか書きたいと思います。

そんな感じでした！

<追記: 2017.08.06>
OAuth認証でログインについての記事を公開しました！
こちらもぜひご覧ください。
[LaravelでInstagramでログインをやってみた](http://qiita.com/daiki_44/items/6d01029cd3a7e7111c9a?get_all_media)