Integrating PHP applications with Instagram, Part 2

Use the Instagram API to integrate photos from Instagram with a PHP app

Instagram is a popular photo-sharing service that enables users to take photos with their smartphone and share them with others through the Web. Application developers can search for and retrieve these photos, together with their associated comments and likes, through the Instagram REST API. This two-part article introduces the Instagram API and illustrates how it can be used with PHP to leverage Instagram's rich repository of user-generated content and to create innovative web applications.

Share:

Vikram Vaswani, Founder, Melonfire

Photo of Vikram VaswaniVikram Vaswani is the founder and CEO of Melonfire, a consulting services firm with special expertise in open-source tools and technologies. He is also the author of the books Zend Framework: A Beginners Guide and PHP: A Beginner's Guide.



01 February 2013

Also available in Russian Japanese

Introduction

In the first part of this article, I introduced you to the Instagram API, explained how it works, and walked you through the basic elements of an Instagram API response. I also showed you how to use the Instagram API with PHP to search for and retrieve photos by tag and by location, as well as how to retrieve complete image meta data, including comments and likes.

The examples in the first part of the article focused primarily on API endpoints that didn't require OAuth-based user authorization. Once you add OAuth to the mix, it becomes possible to access even more information through the API. In this second and concluding part, I explain how to add OAuth authentication to your PHP application and then use the OAuth token to request protected API endpoints, such as the authenticated user's photo feed and relationships feed. I also discuss some third-party PHP libraries that can ease your Instagram API experience.


Searching for users

Let's begin with a look at some of the user endpoints available in the Instagram API. The /users/search method lets you search Instagram for users matching a search term. Consider Listing 1, which illustrates this search in action.

Listing 1. Searching for users
<html>
  <head></head>
  <body>
    <h1>Instagram User 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');

      // define consumer key and secret
      // available from Instagram API console
      $CLIENT_ID = 'YOUR-CLIENT-ID';
      $CLIENT_SECRET = 'YOUR-CLIENT-SECRET';

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

        // get and display users
        $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">
              <img src="' . $item->profile_picture . '" /> <br/>' . 
              $item->username . ' (' . $item->full_name . ') </li>';
          }
          echo '</ul>';
        }
      } catch (Exception $e) {
        echo 'ERROR: ' . $e->getMessage() . print_r($client);
        exit;
      }
    }  
    ?>
  </body>
</html>

Listing 1 produces a web form for the user to enter a search term. It then connects to the Instagram API, requests the /users/search method with the search term as parameter, and retrieves a list of matching users. For each user, the script displays the user's profile picture, username, and full name. Figure 1 has an example of the output.

Figure 1. Searching for users
Screen capture showing results of a search for users

Retrieving User profiles

Just as you can retrieve a list of users, the Instagram API also lets you retrieve the details of any specific user, using the /users/[user-id] method, which returns a JSON document containing details of the specified user. To illustrate, consider Listing 2, which enhances Listing 1 to search for a specific user and display any profile details found.

Listing 2. Retrieving user profiles
<html>
  <head>
    <style>
    #info {
      float: left; 
      width: 300px;
      padding-right: 20px;
    }
    #image {
      float: left; 
      width: 320px;
      padding-right: 20px;
    }    
    </style>  
  </head>
  <body>
    <h1>Instagram User Profile</h1>
    <?php
    if (!isset($_POST['submit'])) {
    ?>
    <form method="post" 
      action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>">
      Search for user:
      <input type="text" name="u" /> 
      <input type="submit" name="submit" value="Search" />      
    </form>
    <?php
    } else {
    ?>
    <?php
      require_once 'Zend/Loader.php';
      Zend_Loader::loadClass('Zend_Http_Client');

      // define consumer key and secret
      // available from Instagram API console
      $CLIENT_ID = 'YOUR-CLIENT-ID';
      $CLIENT_SECRET = 'YOUR-CLIENT-SECRET';

      try {
        // initialize client
        $client = new Zend_Http_Client('https://api.instagram.com/v1/users/search');
        $client->setParameterGet('client_id', $CLIENT_ID);
        $client->setParameterGet('q', $_POST['u']);
        $client->setParameterGet('count', '1');
        
        // search for matching users
        $response = $client->request();
        $result = json_decode($response->getBody());

        // get user id from search results
        if (count($result->data) != 1) {
          echo 'No matches found';
          exit;
        } else {
          $id = $result->data[0]->id;
        }

        // get user's profile information
        $client->setUri('https://api.instagram.com/v1/users/' . $id);
        $client->setParameterGet('client_id', $CLIENT_ID);
        $response = $client->request();
        $result = json_decode($response->getBody());
        $data = $result->data;  
    ?>    
        <div id="image">
          <h2>Image</h2>  
          <img src="<?php echo $result->data->profile_picture; ?>"
            /></a>
        </div>
        <div id="info">
          <h2>Meta</h2>  
          <strong>Username: </strong> 
          <?php echo $result->data->username; ?>
          <br/>
          <strong>Instagram id: </strong> 
          <?php echo $id; ?>
          <br/>
          <strong>Full name: </strong>
          <?php echo !empty($result->data->full_name) ? 
            $result->data->full_name : 'Not specified'; ?>
          <br/>
          <strong>Bio: </strong>
          <?php echo !empty($result->data->bio) ? 
            $result->data->bio : 'Not specified'; ?>
          <br/>
          <strong>Website: </strong>
          <?php echo !empty($result->data->website) ? 
            $result->data->website : 'Not specified'; ?>
          <br/>
          <strong>Instagram photos: </strong>
          <?php echo $result->data->counts->media; ?>
          <br/>
          <strong>Followers: </strong>
          <?php echo $result->data->counts->followed_by; ?>
          <br/>
          <strong>Following: </strong>
          <?php echo $result->data->counts->follows; ?>
          <br/>
        </div>
    <?php    
      } catch (Exception $e) {
        echo 'ERROR: ' . $e->getMessage() . print_r($client);
        exit;
      }
    }  
  ?>
  </body>
</html>

Take a close look at Listing 2, and you'll see that it actually performs two requests to the Instagram API. The first retrieves a list of users matching the search term. If an exact match is found, the second takes care of retrieving details of the specified user with the unique user ID. This happens because the /users/[user-id] endpoint accepts only a user ID, not a username. It's necessary to first search for matching users, then extract the relevant user ID and inject it into the request for the /users/[user-id] endpoint.

The response to a /users/[user-id] API request is a JSON document containing detailed information on the specified user. This information includes the user's Instagram name, full name, profile picture, bio, and Website URL. It also includes a count of the number of photos posted by the user on Instagram, as well as the number of followers and the number of users being followed. Figure 2 displays the output of Listing 2.

Figure 2. Retrieving user profiles
Screen capture of a retrieved user profiles

Working with the self feed

The user endpoints explained in the previous two listings can be accessed using just a client ID. The Instagram API, however, also includes other user endpoints, which can be accessed only by sending a signed OAuth request to the API.

OAuth 2.0 is an in-progress revision of OAuth 1.0. Unlike OAuth 1.0, OAuth 2.0 is not (currently) supported by the Zend Framework, so it's necessary to roll your own code to handle the OAuth 2.0 workflow. The process is made significantly simpler by the PHP-OAuth2 library created by Pierrick Charron and Anis Berejeb, which is available under the GNU LGPL (see Resources for a link). The PHP-OAuth2 library makes it relatively easy to add OAuth 2.0 support to your PHP application.

To see how this works, consider Listing 3, which uses the PHP-OAuth2 library to connect to the Instagram API, request access, and then display a listing of the uploaded photos of the authenticated user as well as those of the users followed by the authenticated user (the so-called "self feed"). This example makes use of the /users/self/feed API method.

Listing 3. Retrieving the self feed
<?php
require('Client.php');
require('GrantType/IGrantType.php');
require('GrantType/AuthorizationCode.php');

const CLIENT_ID     = 'YOUR-CLIENT-ID';
const CLIENT_SECRET = 'YOUR-CLIENT-SECRET';

const REDIRECT_URI           = 'http://localhost/dev/app.php';
const AUTHORIZATION_ENDPOINT = 'https://api.instagram.com/oauth/authorize';
const TOKEN_ENDPOINT         = 'https://api.instagram.com/oauth/access_token';

$client = new OAuth2\Client(CLIENT_ID, CLIENT_SECRET);
session_start();
if (!isset($_SESSION['ACCESS_TOKEN'])) {
  if (!isset($_GET['code'])) {
    $auth_url = $client->getAuthenticationUrl(AUTHORIZATION_ENDPOINT, 
      REDIRECT_URI, array('scope' => 'relationships'));
    header('Location: ' . $auth_url);
    die('Redirect');
  } else {
    $params = array('code' => $_GET['code'], 'redirect_uri' => REDIRECT_URI);
    $response = $client->getAccessToken(TOKEN_ENDPOINT, 'authorization_code', 
      $params);  
    $_SESSION['ACCESS_TOKEN'] = $response['result']['access_token'];
  }
} else {
  $client->setAccessToken($_SESSION['ACCESS_TOKEN']);
}
?>
<html>
  <head></head>
  <body>  
    <h1>Instagram User Feed</h1>  
    <?php
    try {
      // get authenticated user's feed
      $response = $client->fetch('https://api.instagram.com/v1/users/self/feed');
      $result = json_decode(json_encode($response['result']));

      // display images
      $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>

The first part of Listing 3 is the standard OAuth 2.0 workflow, which securely transfers the user to an authorization screen and then transfers control back to the application once the user has authorized the application's access request. Note that the OAuth 2.0 access token generated by this script is stored in a browser session, so subsequent attempts to access protected API endpoints will not require authorization.

Pay attention to the "scope" parameter used in the authentication process, which defines the scope of the authorization. In this case, the "relationships" scope is requested in addition to the default scope because some of the examples in this article demonstrate how to modify user relationships.

The OAuth 2.0 access token generated through this process is attached to the OAuth2 client object, which is then used to request the user's self feed. The JSON response to this request is then parsed as described in the first part of this article, and a web page containing photos by the authenticated user and those he follows are dynamically generated. Figure 3 has an example of what this page looks like.

Figure 3. Displaying photos from the self feed
Screen capture of page displaying photos from the self feed

Searching for photos by user

Listing 3 demonstrated the user's self feed—that is, the feed of photos uploaded by the user and the users he follows. But what if you're actually interested only in one specific user's photos? This search too is possible, with the /users/[user-id]/media/recent API endpoint, which returns a feed of the most recent photos uploaded by a specific user.

The catch is that the /users/[user-id]/media/recent endpoint accepts only a user ID and so, as in Listing 2, you must first find a matching user with the /users/search endpoint. Then you can use the corresponding user ID to request the /users/[user-id]/media/recent endpoint. Listing 4 illustrates the process.

Listing 4. Searching for photos by user
<?php
require_once('oauth-instagram-bootstrap.php');
?>
<html>
  <head></head>
  <body>
    <h1>Instagram Photo Search by User</h1>
    <?php
    if (!isset($_POST['submit'])) {
    ?>
    <form method="post" 
      action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>">
      Search for user:
      <input type="text" name="u" /> 
      <input type="submit" name="submit" value="Search" />      
    </form>
    <?php
    } else {
    ?>
    <?php
      try {
        // search for matching user
        $response = $client->fetch('https://api.instagram.com/v1/users/search', 
          array('count' => 1, 'q' => $_POST['u']));
        $result = json_decode(json_encode($response['result']));
        
        if (count($result->data) != 1) {
          echo 'No matches found';
          exit;
        } else {
          $id = $result->data[0]->id;
        }
      
        // get user's recent image uploads
        $response = $client->fetch('https://api.instagram.com/v1/users/' . 
          $id . '/media/recent');
        $result = json_decode(json_encode($response['result']));

        // display images
        $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>

Figure 4 demonstrates the results of a search

Figure 4. Searching for photos by user
Screen capture showing results of search for photos by user

In Listing 4, the response to the /users/[user-id]/media/recent endpoint contains a collection of photos uploaded by the specified user. It's quite easy to iterate over this collection and, for each photo, display a thumbnail image, basic meta-data, and number of counts and likes.

Note that, in Listing 4 as well as in subsequent examples, the common code for the OAuth 2.0 authorization workflow is stored in a separate bootstrap file that is included at the top of each script. This is done to reduce the length of the code listings in this article and improve readability.


Inspecting user relationships

Like other social networks, Instagram allows users to follow, or be followed by, other users. The Instagram API provides two endpoints to obtain information on user relationships: /users/[user-id]/follows and /users/[user-id]/followed-by. Given a specific user ID, these endpoints return a list of other users either followed by, or following, the specified user. Listing 5 illustrates these endpoints in action.

Listing 5. Retrieving user relationships
<html>
  <head>
    <style>
    #follows {
      float: left; 
      width: 400px;
      padding-right: 20px;
    }
    #followers {
      float: left; 
      width: 400px;
      padding-right: 20px;
    }    
    </style>  
  </head>
  <body>
    <h1>Instagram User Relationships</h1>
    <?php
    if (!isset($_POST['submit'])) {
    ?>
    <form method="post" 
      action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>">
      Search for user:
      <input type="text" name="u" /> 
      <input type="submit" name="submit" value="Search" />      
    </form>
    <?php
    } else {
    ?>
      <h2>Relationships for '<?php echo $_POST['u']; ?>'</h2>
    <?php
      // userid 262796303
      require_once 'Zend/Loader.php';
      Zend_Loader::loadClass('Zend_Http_Client');

      // define consumer key and secret
      // available from Instagram API console
      $CLIENT_ID = 'YOUR-CLIENT-ID';
      $CLIENT_SECRET = 'YOUR-CLIENT-SECRET';

      try {
        // initialize client
        $client = new Zend_Http_Client('https://api.instagram.com/v1/users/search');
        $client->setParameterGet('client_id', $CLIENT_ID);
        $client->setParameterGet('q', $_POST['u']);
        
        // search for matching users
        $response = $client->request();
        $result = json_decode($response->getBody());

        // get user id from search results
        if (count($result->data) != 1) {
          echo 'No matches found';
          exit;
        } else {
          $id = $result->data[0]->id;
        }

        // get who the user follows
        $client->setUri('https://api.instagram.com/v1/users/' . 
          $id . '/follows');
        $client->setParameterGet('client_id', $CLIENT_ID);
        $response = $client->request();
        $result = json_decode($response->getBody());
        $follows = $result->data;
        unset($result);
        
        // get the user's followers
        $client->setUri('https://api.instagram.com/v1/users/' . 
          $id . '/followed-by');
        $client->setParameterGet('client_id', $CLIENT_ID);
        $response = $client->request();
        $result = json_decode($response->getBody());
        $followers = $result->data;  
        
    ?>    
        <div id="follows">
          <h2>Follows</h2>
          <?php
          if (count($follows) > 0) {
            echo '<ul>';
            foreach ($follows as $item) {
              echo '<li style="display: inline-block; padding: 25px">
                <img src="' . $item->profile_picture . '" /> <br/>' . 
                $item->username . ' (' . $item->full_name . ') </li>';
            }
            echo '</ul>';
          } else {
            echo 'Not following anyone';
          }
          ?>
        </div>

        <div id="followers">
          <h2>Followers</h2>
          <?php
          if (count($followers) > 0) {
            echo '<ul>';
            foreach ($followers as $item) {
              echo '<li style="display: inline-block; padding: 25px">
                <img src="' . $item->profile_picture . '" /> <br/>' . 
                $item->username . ' (' . $item->full_name . ') </li>';
            }
            echo '</ul>';
          } else {
            echo 'No followers';
          }
          ?>
        </div>
        
    <?php    
      } catch (Exception $e) {
        echo 'ERROR: ' . $e->getMessage() . print_r($client);
        exit;
      }
    }  
  ?>
  </body>
</html>

Listing 5 produces a web form allowing entry of an Instagram username. Once the form is submitted, Listing 5 first accesses the /users/search API endpoint to find the corresponding user ID, then injects this user ID into requests for the /users/[user-id]/follows and /users/[user-id]/followed-by endpoints. The JSON documents produced by these endpoints are used to display lists of follows and followers, with each list containing the user's profile picture, username, and full name. Figure 5 has an example of the output.

Figure 5. Displaying user relationships
Screen capture of page that displays user relationships

Modifying user relationships

In addition to providing information on a user's relationships, the Instagram API also makes it possible to modify these relationships. The protected /users/[user-id]/relationship endpoint accepts POST requests for "follow", "unfollow", "block", "unblock", "approve", or "deny" actions and performs these actions between the specified user and the current authenticated user. This makes it possible, for example, to set up follower relationships between users directly through the API.

To illustrate, consider Listing 6, which allows the authenticated user to follow any other user by entering a username into a form.

Listing 6. Modifying user relationships
<?php
require_once('oauth-instagram-bootstrap.php');
?>
<html>
  <head>
    <style>
    #follows {
      float: left; 
      width: 400px;
      padding-right: 20px;
    }
    #followers {
      float: left; 
      width: 400px;
      padding-right: 20px;
    }    
    </style>  
  </head>
  <body>
    <h1>Follow on Instagram</h1>
    <?php
    if (!isset($_POST['submit'])) {
    ?>
    <form method="post" 
      action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>">
      Enter name of user to follow:
      <input type="text" name="u" /> 
      <input type="submit" name="submit" value="Search" />      
    </form>
    <?php
    } else {
      // search for matching user
      $response = $client->fetch('https://api.instagram.com/v1/users/search', 
        array('q' => $_POST['u']));
      $result = json_decode(json_encode($response['result']));
      
      if (count($result->data) != 1) {
        echo 'No matches found';
        exit;
      } else {
        $id = $result->data[0]->id;
      }
    
      // get user's recent image uploads
      $response = $client->fetch('https://api.instagram.com/v1/users/' . 
        $id . '/relationship', 
        array('action' => 'follow'), 'POST');
      $result = json_decode(json_encode($response['result']));
      print_r($result); die;
    }  
  ?>
  </body>
</html>

Listing 6 first searches for the username, finds the corresponding Instagram user ID, and then generates a POST request to the /users/[user-id]/relationship endpoint with a "follow" action parameter to establish a follower relationship between the authenticated user and the target user.


Using third-party libraries (1)

So far, all the examples you've seen have involved using an HTTP client to access API endpoints and process responses. If you're not a fan of writing your own code, though, you'll be happy to hear that there also exist various third-party PHP libraries that provide ready-made functionality for working with the Instagram API.

One such library is the PHP Instagram API by Galen Grover, which provides a PHP 5.3+ wrapper for the Instagram API (see Resources for a link). This library provides a set of classes that encapsulate common functionality, making it easier to work with Instagram entities, such as photos, users, tags, and comments. Consider Listing 7, which illustrates how to use this library to retrieve the most popular photos on Instagram.

Listing 7. Retrieving popular images with the PHP Instagram API
<html>
  <head></head>
  <body>  
    <h1>Popular on Instagram</h1>  
    <?php
    // set up autoloader
    function app_autoloader($class) {
      include './' . $class . '.php';
    }
    spl_autoload_register('app_autoloader');

    // define consumer key and secret
    // available from Instagram API console
    $CLIENT_ID = 'YOUR-CLIENT-ID';
    $CLIENT_SECRET = 'YOUR-CLIENT-SECRET';

    // initialize client
    try {
      $instagram = new Instagram\Instagram;
      $instagram->setClientID($CLIENT_ID);

      // get and display popular images
      $media = $instagram->getPopularMedia();
      $data = $media->getData();
      if ($media->count() > 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>

Listing 7 begins by setting up an auto-loader, which automatically loads the library classes as needed. It then initializes an instance of the Instagram class, sets the client ID, and calls the object's getPopularMedia() method to retrieve the list of popular photos from Instagram. The getPopularMedia() method returns a MediaCollection object, which internally holds a collection of media objects. It's now easy to iterate over this collection and retrieve the details of each photo for display on a web page. Figure 6 illustrates the result.

Figure 6. Displaying popular images
Screen capture of page that displays popular images

The PHP Instagram API also supports OAuth requests and comes with built-in wrapper methods for protected API endpoints. To illustrate, consider Listing 8, which recreates Listing 4 using the PHP Instagram API.

Listing 8. Searching for photos by user with the PHP Instagram API
<?php
// set up autoloader
function app_autoloader($class) {
  include './' . $class . '.php';
}
spl_autoload_register('app_autoloader');

// start session
session_start();

// set authentication details
$config = array(
  'client_id'         => 'YOUR-CLIENT-ID',
  'client_secret'     => 'YOUR-CLIENT-SECRET',
  'redirect_uri'      => 'http://localhost/dev/app.php',
);

// perform authentication
if (!isset( $_SESSION['instagram_access_token'] ) ) {
  $auth = new Instagram\Auth($config);
  if (isset($_GET['code'])) {
      $_SESSION['instagram_access_token'] = $auth->getAccessToken( $_GET['code'] );
      header( 'Location: ' . REDIRECT_AFTER_AUTH );
      exit;
  } else {
    $auth->authorize();
  }
  exit;
}
?>
<html>
  <head></head>
  <body>
    <h1>Instagram Photo Search by User</h1>
    <?php
    if (!isset($_POST['submit'])) {
    ?>
    <form method="post" action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>">
      Search for user:
      <input type="text" name="u" /> 
      <input type="submit" name="submit" value="Search" />      
    </form>
    <?php
    } else {
    ?>
    <?php
      try {      
        // set up client
        $instagram = new Instagram\Instagram;
        $instagram->setAccessToken($_SESSION['instagram_access_token']);
        
        // search for matching user
        $user = $instagram->getUserByUsername($_POST['u']);
        $media = $user->getMedia();  
        if ($media->count() > 0) {
          echo '<ul>';
          foreach ($media->getData() 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>

As you can see, Listing 8 is significantly shorter and easier to read than Listing 4. After implementing the necessary OAuth workflow, the listing prompts for a username, then uses the getUserByUsername() method to retrieve details of the specified user as a User object. The User object exposes a getMedia() object, which returns collection of media objects representing recent photo uploads by that user. You can now process this collection to display thumbnails of each uploaded photo, as in Figure 4.


Using third-party libraries (2)

An alternative third-party library is the one developed by Christian Metz, which also provides an easy-to-use PHP class for working with the Instagram API (see Resources for a link). Listing 9 has an example of using it to retrieve popular media from Instagram.

Listing 9. Retrieving popular images with Instagram-PHP-API
<html>
  <head></head>
  <body>  
    <h1>Popular on Instagram</h1>  
    <?php
    require 'instagram.class.php';
    
    // define consumer key and secret
    $CLIENT_ID = 'YOUR-CLIENT-ID';
    $CLIENT_SECRET = 'YOUR-CLIENT-SECRET';

    // initialize client
    try {
      $instagram = new Instagram($CLIENT_ID);

      // get and display popular images
      $media = $instagram->getPopularMedia();

      if (count($media->data) > 0) {
        echo '<ul>';
        foreach ($media->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>

Listing 9 begins by loading the class file, then creating an instance of the Instagram object and using the object's getPopularMedia() method to retrieve a list of popular photos. This method internally calls the /media/popular endpoint and receives and decodes the JSON response. The resulting object can be processed to display a listing of popular media, producing the same output as Listing 7.

It's also possible to recreate Listing 8 using this library, as in Listing 10.

Listing 10. Searching for photos by user with Instagram-PHP-API
<?php
// include class
require 'instagram.class.php';

// define credentials
$config = array(
  'apiKey'        => 'YOUR-CLIENT-ID',
  'apiSecret'     => 'YOUR-CLIENT-SECRET',
  'apiCallback'   => 'http://localhost/dev/app.php',
);

// initialize client
session_start();
$instagram = new Instagram($config);

// performa authentication
if (!isset($_SESSION['IACCESS_TOKEN'])) {
  if (!isset($_GET['code'])) {
    $auth_url = $instagram->getLoginUrl();
    header('Location: ' . $auth_url);
    die('Redirect');
  } else {
    $data = $instagram->getOAuthToken($_GET['code']);  
    $_SESSION['IACCESS_TOKEN'] = $data;
    $instagram->setAccessToken($_SESSION['IACCESS_TOKEN']);
  }
} else {
  $instagram->setAccessToken($_SESSION['IACCESS_TOKEN']);
}

?>
<html>
  <head></head>
  <body>
    <h1>Instagram Photo Search by User</h1>
    <?php
    if (!isset($_POST['submit'])) {
    ?>
    <form method="post" 
      action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>">
      Search for user:
      <input type="text" name="u" /> 
      <input type="submit" name="submit" value="Search" />      
    </form>
    <?php
    } else {
      try {      
        // search for matching user
        $user = $instagram->searchUser($_POST['u']);

        // search for user's photos
        $media = $instagram->getUserMedia($user->data[0]->id);  
        if (count($media->data) > 0) {
          echo '<ul>';
          foreach ($media->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>

Listing 10, like Listing 8, lets users search Instagram for photos by a specific user. It begins by calling the Instagram object's searchUser() method and passing it the username submitted in the web form. The user ID from the resulting user record is then passed to the getUserMedia() method, which returns a list of recent photo uploads by that user.


Conclusion

As these examples demonstrate, the Instagram API provides a full-featured set of endpoints to create PHP-based web applications around the photos stored in the Instagram service. Regardless of whether you're using a third-party PHP library or writing your own code, it's quite easy to access user profiles, relationships and media, and combine information from different endpoints to create custom web applications. Now try it for yourself.

Resources

Learn

Get products and technologies

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into XML on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=XML, Open source, Web development
ArticleID=854971
ArticleTitle=Integrating PHP applications with Instagram, Part 2
publish-date=02012013