Интеграция PHP-приложений с порталом Instagram

Часть 1. Использование API Instagram для ввода фотографий с портала Instagram в PHP-приложение

Instagram — популярная служба обмена фотографиями, пользователи которой делают снимки с помощью своих смартфонов и публикуют их в Интернете. Разработчики приложений могут выполнять поиск среди этих фотографий, а также связанных с ними комментариев и оценок посредством API-интерфейса Instagram на основе REST. Эта статья из двух частей знакомит читателя с API Instagram и показывает, каким образом его можно использовать с PHP для обращения к обширному хранилищу материалов, созданных пользователями Instagram, и создания новаторских Web-приложений.

Викрам Васвани (Vikram Vaswani), основатель компании, Melonfire

Викрам Васвани (Vikram Vaswani) – основатель и президент консалтинговой фирмы Melonfire, специализирующейся на технологиях и инструментах с открытым исходным кодом. Также является автором книг Решения по программированию на PHP and Как сделать все что угодно с помощью PHP и MySQL.



22.05.2013

Введение

Многие владельцы смартфонов Android или Apple, оснащенных фотокамерой, являются пользователями Instagram. Это бесплатное приложение позволяет делать фотоснимки, применять к ним специальные эффекты и фильтры, а затем демонстрировать друзьям на Web-сайте Instagram. Это как Twitter, только вместо твитов ― фотографии. Свыше 100 млн участников по состоянию на сентябрь 2012 года красноречиво свидетельствуют о популярности службы.

Помимо платформы для обмена фотографиями между пользователями, Instagram предоставляет богатый API для разработчиков, который позволяет им обращаться к сгенерированной пользователями информации и создавать Web-приложения, управляемые контентом. К этому API, который следует модели REST, можно обращаться на любом языке программирования, который понимает JSON, включая мой любимый PHP.

Эта статья из двух частей знакомит читателя с API Instagram и показывает, как интегрировать и использовать собранные пользователями Instagram материалы с PHP-приложениями. Она содержит примеры каналов для извлечения фотографий и комментариев, поиска фотографий по ключевым словам или местоположению, извлечения профилей и управления взаимоотношениями с пользователями. Итак, приступим!


Начало работы

Прежде чем приступить к разработке приложений с помощью API Instagram, нужно понять, как он работает. Как и многие другие Web-интерфейсы, API Instagram работает по протоколу HTTP и ожидает HTTP-запросов к назначенной оконечной точке. Получив такой запрос, сервер API отвечает на него сообщением JSON, содержащим запрашиваемые данные. Эти данные можно проанализировать с помощью программы на языке программирования для сервера (таком как PHP или Perl) или инструментов на стороне клиента (таких как jQuery или mooTools) и извлечь информацию для размещения на Web-странице.

Чтобы увидеть, как это работает, нужно сделать две вещи:

  1. Создать учетную запись Instagram. Регистрация бесплатна, и эту задачу можно решить с помощью приложения Instagram для Android, iPhone или iPad. Зарегистрировавшись, выберите несколько фотографий со своего смартфона и загрузите их в свою учетную запись Instagram.
  2. Создать клиентское приложение, чтобы получить доступ к API Instagram. Войдите на сайт Instagram через учетную запись, созданную на предыдущем шаге, и зарегистрируйте новый клиент посредством консоли разработчика (см. раздел Ресурсы). Нужно будет ввести основную информацию о клиенте, такую как имя и описание, а также URL обратного вызова для аутентификации OAuth 2.0 (рисунок 1).
    Рисунок 1. Регистрация клиента Instagram (Register new OAuth Client)
    Регистрация клиента Instagram (Register new OAuth Client)

    После передачи этой информации клиенту присваивается уникальный идентификатор и секретный ключ (рисунок 2). Примите их к сведению, так как они понадобятся вам для доступа к API Instagram посредством OAuth 2.0.

    Рисунок 2. Регистрация клиента Instagram
    Регистрация клиента Instagram

Зная идентификатор и секретный ключ клиента, можно создавать подписанные запросы OAuth 2.0 к API Instagram. Протокол и рабочий процесс OAuth 2.0 хорошо документированы (см. ссылки на документацию в разделе Ресурсы). В этой статье мы не будем вдаваться в подробности; следующие примеры просто демонстрируют, как реализовать этот рабочий процесс с помощью API Instagram.

Обратите внимание, что использование API Instagram в сторонних приложениях регулируется условиями использования API Instagram. Потратьте несколько минут и прочтите этот документ, прежде чем переходить к разработке, чтобы гарантировать соблюдение всех необходимых правил. Соответствующие ссылки приведены в разделе Ресурсы.


Список популярных изображений

Прежде чем приступить к PHP-программированию, рассмотрим, как работает API Instagram. Как и все службы на основе REST, метод API вызывается путем HTTP-запроса к назначенной оконечной точке ресурсов. Этот HTTP-запрос содержит один или несколько входных параметров; сервер обрабатывает эти параметры и возвращает ответ JSON, который можно проанализировать и использовать на Web-странице. Для обеспечения безопасности все запросы API Instagram должны выполняться через SSL.

API Instagram предлагает целый ряд оконечных точек. Имеются оконечные точки для фотографий, комментариев, оценок, тегов, местоположения, пользователей и отношений между пользователями. Для доступа к некоторым оконечным точкам достаточно передать в качестве параметра запроса идентификатор клиента; другие требуют подписанного запроса OAuth 2.0.

Типичный пакет ответа Instagram содержит подробное сообщение с фотографиями и соответствующей информацией. Чтобы увидеть пример, откройте Web-браузер и направьте запрос к оконечной точке API https://api.instagram.com/v1/media/popular?client_id= xx (замените xx в URL своим идентификатором клиента Instagram). Этот запрос должен вызвать сообщение JSON со списком наиболее популярных на данный момент фотографий в Instagram. Пробежимся по этому результату (рисунок 3), чтобы ознакомиться с его основными элементами. Как видите, ответный документ содержит список популярных фотографий, для каждой из которых указаны URL-адрес (эскиза, и версий с низким и с высоким разрешением), заголовок, метки, время создания, комментарии, оценка, фильтр, местоположение, короткий URL, информация о пользователе и многое другое.

Рисунок 3. Пример ответа API Instagram
Пример ответа API Instagram

Эту информацию легко отформатировать в наглядную Web-страницу с помощью функции PHP json_decode() и простого HTML-кода. Это иллюстрирует листинг 1.

Листинг 1. Получение популярных изображений
<html>
  <head></head>
  <body>  
    <h1>Popular on Instagram</h1>  
    <?php
    // загрузка классов Zend
    require_once 'Zend/Loader.php';
    Zend_Loader::loadClass('Zend_Http_Client');

    // определение ключа и секретного ключа пользователя
    // доступно с консоли API Instagram
    $CLIENT_ID = 'YOUR-CLIENT-ID';
    $CLIENT_SECRET = 'YOUR-CLIENT-SECRET';

    try {
      // инициализация клиента
      $client = new Zend_Http_Client('https://api.instagram.com/v1/media/popular');
      $client->setParameterGet('client_id', $CLIENT_ID);

      // получение списка популярных изображений
      // передача запроса и декодирование ответа
      $response = $client->request();
      $result = json_decode($response->getBody());

      // отображение фотографий
      $data = $result->data;  
      if (count($data) > 0) {
        echo '<ul>';
        foreach ($data as $item) {
          echo '<li style="display: inline-block; padding: 25px"><a href="' . 
            $item->link . '"><img src="' . $item->images->thumbnail->url . 
            '" /></a> <br/>';
          echo 'By: <em>' . $item->user->username . '</em> <br/>';
          echo 'Date: ' . date ('d M Y h:i:s', $item->created_time) . '<br/>';
          echo $item->comments->count . ' comment(s). ' . $item->likes->count . 
            ' likes. </li>';
        }
        echo '</ul>';
      }

    } catch (Exception $e) {
      echo 'ERROR: ' . $e->getMessage() . print_r($client);
      exit;
    }
    ?>
  </body>
</html>

Листинг 1 начинается с создания экземпляра автозагрузчика Zend Framework и инициализации экземпляра класса Zend_Http_Client. Этот клиент используется для создания и передачи запроса GET на популярные изображения в оконечную точку API Instagram https://api.instagram.com/v1/media/popular. Обратите внимание, что URL-адрес оконечной точки должен содержать идентификатор клиента, сгенерированный через консоль разработчика Instagram.

Затем ответ JSON на этот запрос анализируется и преобразуется в PHP-объект с помощью функции PHP json_decode(). Если сравнить код из листинга 1 с необработанным объектом JSON, показанным на рисунке 3, то можно заметить соответствие между членами объекта и парами ключ-значение JSON. Теперь можно выполнить итерацию по членам объекта, извлечь данные отдельных изображений (таких как URL-адрес изображения, имя пользователя, время создания, комментарий и оценка) и отформатировать их для отображения на Web-странице. Рисунок 4 иллюстрирует, как выглядит результат.

Рисунок 4. Список популярных изображений
Web-страница со списком популярных изображений

Поиск изображений по метке

Как показано на рисунке 3, каждое изображение Instagram можно связать с одной или несколькими метками, которые представляют собой описательные ключевые слова и которые можно использовать для классификации изображений. API Instagram содержит оконечные точки для поиска и извлечения меток. Чаще всего используется оконечная точка /tags/search, которая позволяет искать метки, совпадающие с условиями поиска. Листинг 2 демонстрирует использование этой оконечной точки.

Листинг 2. Поиск по тегам
<html>
  <head></head>
  <body>
    <h1>Instagram Tag Search</h1>
    <?php
    if (!isset($_POST['submit'])) {
    ?>
    <form method="post" 
      action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>">
      Search for:
      <input type="text" name="q" /> 
      <input type="submit" name="submit" value="Search" />      
    </form>
    <?php
    } else {
    ?>
    <h2>Search results for '<?php echo $_POST['q']; ?>'</h2>
    <?php
      require_once 'Zend/Loader.php';
      Zend_Loader::loadClass('Zend_Http_Client');

      // определение ключа и секретного ключа пользователя
      // доступно с консоли API Instagram
      $CLIENT_ID = 'YOUR-CLIENT-ID';
      $CLIENT_SECRET = 'YOUR-CLIENT-SECRET';

      try {
        // инициализация клиента
        $client = new Zend_Http_Client('https://api.instagram.com/v1/tags/search');
        $client->setParameterGet('client_id', $CLIENT_ID);
        $client->setParameterGet('q', $_POST['q']);

        // получение и отображение аналогичных меток
        $response = $client->request();
        $result = json_decode($response->getBody());
        $data = $result->data;  
        if (count($data) > 0) {
          echo '<ul>';
          foreach ($data as $item) {
            echo '<li>' . $item->name . ' (' . $item->media_count . 
              ') </li>';
          }
          echo '</ul>';
        }
      } catch (Exception $e) {
        echo 'ERROR: ' . $e->getMessage() . print_r($client);
        exit;
      }
    }  
    ?>
  </body>
</html>

Листинг 2 начинается с создания простой Web-формы для ввода пользователем условий поиска. После отправки формы инициализируется новый объект Zend_Http_Client и создается запрос к оконечной точке /tags/search, аналогичный тому, что был описан для листинга 1. Условие поиска, введенное пользователем, поступает в эту оконечную точку в качестве параметра запроса в аргументе запроса "q".

Ответ на этот запрос представляет собой коллекцию меток, соответствующих условию поиска. Эту информацию можно расшифровать и отформатировать в Web-страницу, создавая результат вроде того, что показан на рисунке 5.

Рисунок 5. Список меток
Результаты поиска по ключевому слову «пляж», список меток

Обычно ищут не сами метки, а соответствующие им фотографии. Для этого используется оконечная точка /tags/[tag-name]/media/recent. Как можно догадаться из ее структуры, эта оконечная точка выдает список изображений, недавно помеченных указанной меткой. В листинге 3 приведено простое приложение для поиска фотографий по меткам в Instagram, иллюстрирующее метки в действии.

Листинг 3. Поиск изображений по метке
<html>
  <head></head>
  <body>
    <h1>Instagram Photo Search by Tag</h1>
    <?php
    if (!isset($_POST['submit'])) {
    ?>
    <form method="post" 
      action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>">
      Search for:
      <input type="text" name="q" /> 
      <input type="submit" name="submit" value="Search" />      
    </form>
    <?php
    } else {
    ?>
    <h2>Search results for '<?php echo $_POST['q']; ?>'</h2>
    <?php
      require_once 'Zend/Loader.php';
      Zend_Loader::loadClass('Zend_Http_Client');

      // определение ключа и секретного ключа пользователя
      // доступно с консоли API Instagram
      $CLIENT_ID = 'YOUR-CLIENT-ID';
      $CLIENT_SECRET = 'YOUR-CLIENT-SECRET';

      try {
        // initialize client
        $client = new Zend_Http_Client('https://api.instagram.com/v1/tags/'. 
          $_POST['q'] . '/media/recent');
        $client->setParameterGet('client_id', $CLIENT_ID);

        // получение изображений с соответствующими метками
        // передача запроса и декодирование ответа
        $response = $client->request();
        $result = json_decode($response->getBody());

        // отображение фотографий
        $data = $result->data;  
        if (count($data) > 0) {
          echo '<ul>';
          foreach ($data as $item) {
            echo '<li style="display: inline-block; padding: 25px"><a href="' . 
              $item->link . '"><img src="' . $item->images->thumbnail->url . 
              '" /></a> <br/>';
            echo 'By: <em>' . $item->user->username . '</em> <br/>';
            echo 'Date: ' . date ('d M Y h:i:s', $item->created_time) . '<br/>';
            echo $item->comments->count . ' comment(s). ' . $item->likes->count . 
              ' likes. </li>';
          }
          echo '</ul>';
        }

      } catch (Exception $e) {
        echo 'ERROR: ' . $e->getMessage() . print_r($client);
        exit;
      }
    }  
    ?>
  </body>
</html>

Листинг 3 представляет собой гибрид листинга 1 и листинга 2. Это Web-форма для ввода пользователем условий поиска. Эти условия применяются в качестве метки, которая отправляется в запросе к оконечной точке /tags/[tag-name]/media/search для поиска подходящих фотографий. Полученная в результате коллекция объектов обрабатывается, как показано в листинге 1, для создания страницы, содержащей эскизы изображений и основную информацию профилей. Пример результата показан на рисунке 6.

Рисунок 6. Список изображений, выбранных по метке
Список изображений, соответствующих метке

Поиск изображений по местоположению

Изображения можно искать и по местоположению. Оконечная точка /media/search принимает параметры "lat" (широта) и "long" (доллгота) и выдает соответствующие изображения. Иллюстрация приведена в листинге 4, который позволяет вводить значения географических координат и генерирует список изображений, соответствующих указанной области.

Листинг 4. Поиск изображений по местоположению
<html>
  <head></head>
  <body>
    <h1>Instagram Photo Search by Location</h1>
    <?php
    if (!isset($_POST['submit'])) {
    ?>
    <form method="post" 
      action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>">
      Latitude: <input type="text" name="lat" />  
      Longitude: <input type="text" name="long" /> 
      <input type="submit" name="submit" value="Search!" />      
    </form>
    <?php
    } else {
    ?>
    <h1>Search results for 'lat:<?php echo $_POST['lat']; ?>, 
      long:<?php echo $_POST['long']; ?>'</h1>
    <?php
      require_once 'Zend/Loader.php';
      Zend_Loader::loadClass('Zend_Http_Client');

      // определение ключа и секретного ключа пользователя
      // доступно с консоли API Instagram
      $CLIENT_ID = 'YOUR-CLIENT-ID';
      $CLIENT_SECRET = 'YOUR-CLIENT-SECRET';

      try {
        // инициализация клиента
        $client = new Zend_Http_Client('https://api.instagram.com/v1/media/search');
        $client->setParameterGet('client_id', $CLIENT_ID);
        $client->setParameterGet('lat', $_POST['lat']);
        $client->setParameterGet('lng', $_POST['long']);

        // получение изображений, соответствующих указанному местоположению
        $response = $client->request();
        $result = json_decode($response->getBody());

        // отображение фотографий
        $data = $result->data;  
        if (count($data) > 0) {
          echo '<ul>';
          foreach ($data as $item) {
            echo '<li style="display: inline-block; padding: 25px"><a href="' . 
              $item->link . '"><img src="' . $item->images->thumbnail->url . 
              '" /></a> <br/>';
            echo 'By: <em>' . $item->user->username . '</em> <br/>';
            echo 'Date: ' . date ('d M Y h:i:s', $item->created_time) . '<br/>';
            echo $item->comments->count . ' comment(s). ' . $item->likes->count . 
              ' likes. </li>';
          }
          echo '</ul>';
        }

      } catch (Exception $e) {
        echo 'ERROR: ' . $e->getMessage() . print_r($client);
        exit;
      }
    }  
    ?>
  </body>
</html>

На рисунке 7 показан результат поиска изображений по координатам 18.9218 N, 72.8347 E, которые соответствуют местоположению монумента "Ворота в Индию" в Бомбее.

Рисунок 7. Список изображений, найденных по местоположению
Список изображений, найденных по местоположению

Обратите внимание, что область поиска можно расширить с 1 км до 5 км, добавив в запрос параметр distance. Хотя здесь это не отражено, Instagram также предоставляет оконечную точку API /locations, которую можно использовать для получения сведений о конкретном месте.


Получение описания изображения

В предыдущих примерах показано, как найти набор изображений, соответствующих определенным критериям. Instagram также предоставляет оконечную точку /media/[media-id], которую можно использовать для получения подробных сведений о конкретном изображении. Рассмотрим листинг 5, который иллюстрирует характер информации, передаваемой через эту оконечную точку.

Листинг 5. Получение сведений об изображении
<html>
  <head>
    <style>
    #container {
      margin: 0 auto;    
    }
    #info {
      float: left; 
      width: 300px;
      padding-right: 20px;
    }
    #image {
      float: left; 
      width: 320px;
      padding-right: 20px;
    }    
    #comments {
      clear: both;
    }
    .item {
      float:none;
      clear:both;
      margin-top:1em;  
    }
    .profile {
      float:left;
      margin-right:1em; 
      padding-bottom: 10px;
      height: 48px;
      width: 48px;
    }
    </style>
  </head>
  <body>  
    <h1>Instagram Image Detail</h1>
    <?php
    // загрузка классов Zend
    require_once 'Zend/Loader.php';
    Zend_Loader::loadClass('Zend_Http_Client');

    // определение ключа и секретного ключа пользователя
    // доступно с консоли API Instagram
    $CLIENT_ID = 'YOUR-CLIENT-ID';
    $CLIENT_SECRET = 'YOUR-CLIENT-SECRET';

    try {
      // определение id изображения
      $image = '338314508721867526';

      // инициализация клиента
      $client = new Zend_Http_Client('https://api.instagram.com/v1/media/' . $image);
      $client->setParameterGet('client_id', $CLIENT_ID);

      // получение метаданных изображения
      $response = $client->request();
      $result = json_decode($response->getBody());

      // отображение сведений об изображении
    ?>
      <div id="container">
        <div id="info">
          <h2>Meta</h2>  
          <strong>Date: </strong> 
          <?php echo date('d M Y h:i:s', $result->data->created_time); ?>
          <br/>
          <strong>Creator: </strong>
          <?php echo $result->data->user->username; ?>
          (<?php echo !empty($result->data->user->full_name) ? 
            $result->data->user->full_name : 'Not specified'; ?>)
          <br/>
          <strong>Location: </strong>
          <?php echo !is_null($result->data->location) ?
          $result->data->location->latitude . ',' . 
            $result->data->location->longitude : 'Not specified'; ?>
          <br/>
          <strong>Filter: </strong>
          <?php echo $result->data->filter; ?>
          <br/>
          <strong>Comments: </strong>
          <?php echo $result->data->comments->count; ?>
          <br/>
          <strong>Likes: </strong>
          <?php echo $result->data->likes->count; ?>
          <br/>
          <strong>Resolution: </strong>
          <a href="<?php echo $result->data->images
            ->standard_resolution->url; ?>">Standard</a> | 
          <a href="<?php echo $result->data->images
            ->thumbnail->url; ?>">Thumbnail</a>
          <br/>
          <strong>Tags: </strong>
          <?php echo implode(',', $result->data->tags); ?>
          <br/>
        </div>
        <div id="image">
          <h2>Image</h2>  
          <img src="<?php echo $result->data->images
            ->low_resolution->url; ?>" /></a>
        </div>
        <div id="comments">
          <?php if ($result->data->comments->count > 0): ?>
          <h2>Comments</h2>
          <ul>
            <?php foreach ($result->data->comments->data as $c): ?>
              <div class="item"><img src="<?php echo $c
                ->from->profile_picture; ?>" class="profile" />
              <?php echo $c->text; ?> <br/>
              By <em> <?php echo $c->from->username; ?></em> 
              on <?php echo date('d M Y h:i:s', $c->created_time); ?>
              </div>

              </li>
            <?php endforeach; ?>
          </ul>
          <?php endif; ?>
        </div>      
      </div>
    <?php
    } catch (Exception $e) {
      echo 'ERROR: ' . $e->getMessage() . print_r($client);
      exit;
    }
    ?>
  </body>
</html>

После загрузки библиотеки Zend_Http_Client код, приведенный в листинге 5, создает запрос к оконечной точке /media/[media-id] с идентификатором изображения, встроенным в URI запроса. Идентификатор изображения обычно содержится в каждом результате поиска, а также в других метаданных фотографии.

В ответ на запрос API /media/[media-id] приходит JSON-документ, содержащий подробную информацию об указанном изображении. В эту информацию входят дата и время создания изображения, имя пользователя, широта и долгота, фильтр Instagram, примененный к фото, и количество оценок и комментариев. Возвращенные данные также включают URL-адрес трех версий изображения — эскиза, версии с низким разрешением и версии с высоким разрешением — вместе со списком прикрепленных меток. К JSON-документу добавляется перечень последних комментариев; как видно из листинга и результата, этот список можно обработать, чтобы отображать комментарии на фотографии вместе с именем пользователя и изображением из его профиля.

На рисунке 8 показан результат листинга 5. Как свидетельствуют выходные данные, Instagram API позволяет отображать все сведения, которые найдутся в приложении и на Web-сайте Instagram, посредством специального PHP-приложения.

Рисунок 8. Отображение деталей изображения
Сведения об изображении

Все это только верхушка айсберга. API Instagram также позволяет разработчикам обращаться к аутентифицируемым каналам фотографий пользователей, искать фотографии определенных пользователей, создавать отношения для наблюдения за пользователями и многое другое. В большинстве случаев эти операции, связанные с пользователями, могут выполняться только с помощью подписанных запросов OAuth 2.0, для чего разработчик должен реализовать рабочий процесс OAuth 2.0. Этот и другие аспекты API Instagram рассматриваются во второй части статьи, так что до скорой встречи!

Ресурсы

Научиться

Получить продукты и технологии

  • Zend Framework: загрузите эту популярную платформу для высокопроизводительных PHP-приложений.

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=XML, Open source, Web-архитектура
ArticleID=931042
ArticleTitle=Интеграция PHP-приложений с порталом Instagram
publish-date=05222013