Using the Twitter API with PHP and PEAR

Using the Twitter API with PHP and PEAR

Tweet Tweet!

Unless you’ve been living in a cave for the last few years, you know what Twitter is – a free online service that allows users to send out concise, real-time updates on what they’re doing at any given moment. These status updates, or “tweets”, can be sent and received through SMS, via the Twitter Web site, or through a variety of third-party applications, and users can subscribe to, or “follow”, each other’s status feeds. Twitter also supports private messaging and search, and has rapidly been growing in popularity as a tool for social networking and near real-time communication.

The really good stuff, though, is hidden behind the scenes. Like many Web 2.0 applications, Twitter exposes its innards to the public via a REST API, making it possible to develop customized applications that run on top of the base service. A number of third-party libraries, written in a variety of different programming languages (including PHP), exist to help developers integrate their applications with this API. This article focuses on one such library, the PEAR Services_Twitter library, which provides a full-featured API for interacting with the Twitter service through a PHP application.

Starting Up

Services_Twitter works by providing a full-fledged, object-oriented interface to the Twitter API. This interface insulates you from the nitty-gritty of working directly with REST requests and, by representing responses as SimpleXML objects, makes it very easy to access specific elements of the returned data. This not only saves time; it’s also simpler, because it’s no longer necessary to be intimately aware of the nitty-gritties of the Twitter API in order to use it effectively.

Before we get started, it’s important to state the assumptions this tutorial makes:

First, it assumes that you understand HTML, know the basics of PHP programming with objects and SimpleXML, and are familiar with REST concepts. It also assumes that you have an Apache/PHP/MySQL development environment already set up.

Second, it assumes that your PHP installation includes support for the cURL extension. On UNIX systems, this support needs to be enabled at compile-time, by adding the --with-curl option to the configuration script. On Windows, the cURL extension is already included, and simply needs to be activated in the php.ini configuration file. More information on installing this extension can be found here.

Third, it assumes that you’ve managed to successfully install the Services_Twitter package. For your reference, this package is freely available from the PEAR Web site, and is currently maintained by Joe Stump and David Jean Louis. This article uses v0.2.0 (beta) of Services_Twitter. To install this package using the PEAR installer, use the following command:

The Services_Twitter package contains separate sub-classes, or “drivers”, for different areas of the Twitter API. For example, there’s a Services_Twitter_Statuses class for status manipulation, and a Services_Twitter_Account class for user account manipulation. These sub-classes are “lazily loaded” by the main Services_Twitter class as needed.

Looking at the example above, it’s clear then that the first order of business is to include the Services_Twitter class file and create a new Services_Twitter object, $service, which represents a Twitter API client. Passing the object constructor a valid Twitter user name and password initializes the client. Once initialized, the call to $service->statuses->update() method loads the Services_Twitter_Statuses sub-class and invokes its update() method, which creates and transmits a POST request to the Twitter server. At the Twitter end of things, the Twitter server receives this POST request, verifies the user authentication credentials, and updates the user’s status to reflect the new value. The $service->account->end_session() call then terminates the user session.

You can also make this a little more fun, by presenting users with a Web form that allows them to interactively update their status on the Twitter Web site. Here’s the code:

This script is divided into two parts, separated by a conditional test which checks if the form has been submitted or not. If not, a simple HTML form, with fields for the user’s Twitter screen name, password and status message is generated. On submission, the second half of the script comes into play: it loads the Services_Twitter client, uses the supplied credentials to log in to the Twitter Web site, and updates the user’s status message as described for the previous listing.

Here are some images showing this script in action:

Once submitted, the revised status should also be visible on the user’s Twitter page:

When using the Services_Twitter package with the Twitter API, there are a few important things to keep in mind:

The Twitter API currently supports HTTP Basic authentication as its authentication scheme. However, OAuth support is currently being tested and should be out of beta shortly. When this happens, the Services_Twitter package will also be updated to use this authentication scheme.

The Twitter API uses HTTP response codes to indicate whether a particular request succeeded or failed. The Services_Twitter package already knows about these error codes, and will automatically parse response packets, retrieve error messages and turn them into PEAR-compliant exceptions, which can be caught using standard try-catch blocks.

The Twitter API can produce output in both XML and JSON formats, but the Services_Twitter package defaults to XML. The exception to this is the Twitter Search API, which currently produces output only in Atom and JSON formats; here, Services_Twitter defaults to JSON. You’ll see an example of using the Twitter Search API with the Services_Twitter package a little further along in this tutorial.

Twitter allows API clients only 100 requests per hour. You can request a higher limit by writing to Twitter administrators with details of your application.

Passing Time

In addition to posting new status updates, the Services_Twitter package also allows developers to retrieve previously-posted updates by the authenticating user, via the Services_Twitter_Statuses::user_timeline() method. Here’s an example:

Here, the user_timeline() method generates a list of the 20 most recent status updates for the logged-in user. This list can easily be processed as an array of SimpleXML elements using a foreach() loop. In particular, take note of the $status->text, $status->user->screen_name and $status->created_at properties, which represent the status message, account name and status update time respectively.

Here’s a sample of what the output looks like:

Two alternatives to the user_timeline() method are the friends_timeline() method, which returns the 20 most recent status updates by the logged-in user and his/her friends, and the public_timeline() method, which returns the 20 most recent public status updates. Here’s an example of these methods in use:

Notice that this listing also makes use of the $status->user->profile_image_url property, to display a thumbnail image of the user’s profile picture in the output. Here’s what it looks like:

Follow The Leader

Twitter makes a distinction between “friends” – the users you follow – and “followers” – the users following you. And Twitter’s API makes it possible to programmatically obtain listings of both your friends and followers, together with their current status. This capability is replicated in the Services_Twitter package, via the Services_Twitter_Statuses::friends() and Services_Twitter_Statuses::followers() methods. To illustrate these methods, consider the following listing, which displays the currently logged-in user’s friends and followers, together with their current status and profile image:

The return value of the friends() and followers() methods is a collection of objects, each representing a Twitter user. It’s easy to access information about each of these users from the various object properties, as shown above. Here’s what the output might look like:

You can also obtain another Twitter user’s friends, by passing the target’s screen name to the friends() method using the ‘id’ parameter. Consider the next example, which illustrates by setting up a Web form that lets you view any Twitter user’s friends:

When this form is submitted, the screen name supplied by the user is passed to the friends() method in an “options” array. The method then queries the Twitter API for this user’s friends and displays a neat listing, as shown below:

You can build a similar form to interactively list any user’s followers (note that this requires authentication):

Here, the target user’s screen name is provided to the followers() method as second argument. Here’s an example of the form and result page:

Developers can also use the Services_Twitter package to generate follower relationships between Twitter user, by invoking the Services_Twitter_Friendships::create() method. Consider the following example, which creates a Web form similar to that of the previous example and initiates a follower relationship between the logged-in user and the specified target user:

There’s also a Services_Twitter_Friendships::destroy() method, which can be used to remove a follower relationships.

The Direct Approach

The Twitter API supports sending direct messages between a user and his/her followers. Here’s an example of how you can leverage this feature and build it into your own application, using the Services_Twitter_DirectMessages::new() method:

This script generates a Web form that asks for your Twitter user credentials, the name of the follower to whom you wish to send a message, and the message body. On submission, the script will attempt to send a direct message to the specified user via the Services_Twitter_DirectMessages::new() method, which accepts two arguments: the recipient’s Twitter username, and the message body.

Here’s an example of the form, and the result when the message is successfully sent:

Note that if you enter the name of a user who is not following you, Twitter will disallow your message with an error code, an exception will be raised in the script, and you’ll end up with an error like the one below:

You can also obtain a list of the 20 most recent direct messages sent by and to the logged-in user with the Services_Twitter_DirectMessages::sent() and Services_Twitter::direct_messages() methods respectively. Here’s an example illustrating these methods in use:

In both cases, each direct message object returned by Twitter contains two nested user objects, one each for the sender and recipient, in addition to the message text. The example above illustrates how these nested objects can be used to retrieve sender and recipient information. Here’s what the output might look like:

You can also get a list of the 20 most recent mentions (tweets containing the authenticating user’s screen name) by invoking Services_Twitter_Statuses::mentions(). This method isn’t explicitly defined in the Services_Twitter package; however, through the power of the __call() “magic method”, Services_Twitter will intelligently determine the URL endpoint for the method in the Twitter API and present the results. Here’s the code:

Searching For Godot

Twitter also offers a Search API, which can be used to find tweets matching a given term and which makes it easy to integrate Twitter search results into your application. This Search API is currently distinct from the “regular” Twitter API you’ve seen in previous examples (although plans are underway to merge the two) and currently produces output only in Atom and JSON formats. Don’t let that bother you too much, though – the Services_Twitter package can handle JSON output without breaking a sweat!

Here’s an example of retrieving Twitter’s top 10 trends at any given moment, using the Services_Twitter_Search::trends() method:

Retrieving tweets matching a particular query term is equally simple – just pass the query term to the Services_Twitter_Search::query() method, and iterate over the resulting object collection. Here’s an example, which builds an interactive search form and, on submission, searches Twitter for the input term:

Note that the Twitter Search API supports a variety of optional modifiers that can be used to filter the result set, such as the language ('lang') or location ('geocode'). However, these modifiers are not currently supported by the Services_Twitter_Search::query() method.

These examples are just the tip of the iceberg: the Services_Twitter package includes support for various other aspects of the Twitter experience, including adding and removing favorites, viewing extended user information, and changing account settings. The package’s well-defined interface to the Twitter API takes the pain out of directly formulating and executing REST queries, and it can significantly reduce the drudge work of integrating Twitter into your application. As such, it’s a valuable addition to any programmer’s toolkit, and one that you should definitely take some time out to experiment with. Take a look at it sometime, and see what you think!

Hi, just wanted to know if you have a demo page for this one or maybe a file that has everything on it already? I’m new to PHP and I wanna know more about this. Please help me. If you can post a compressed file for this great tutorial, it would be great

Of course, I feel like the class slow poke, because I am stuck on the assumption regarding installing the Twitter_Services package from the PEAR website. Now I am on the phone with my friends at Godaddy, and they are checking up the line to see whether I can install with the pear installer on my shared linux hosting account. I do know curl is on there, because I use it already for posting updates to Twitter.

Just passing along the situation, so other encountering it will know they are not alone.

Hello,
first of all thank you for the article : clear and well written.
I requested fro twitter to remove limitations on my account, and I can see it is ok, but when I run the script for example to get my friends list, I only get 100 accounts.
Is there any setting I have to do?
thank you again and in advance for any answer.