Location-based services like Foursquare are all the rage. If you haven't heard about them yet, you will. It seems that everywhere you turn, people are using Foursquare, Gowalla, Loopt, and other tools to "check in" to their favorite locations, share tips with other users about favorite drinks or dishes, and share all of this activity on other services like Twitter and Facebook.
As a developer, you have to know this stuff. Social, and specifically, location-based services that use social platforms, represent a huge growth area for web and mobile developers. Most of these services use some kind of RESTful service you can use to request JavaScript Serialized Object Notation (JSON) or XML data. Some, such as Facebook, don't require much authentication, while others, like Foursquare, have some feeds that do require authentication and some that don't.
For the purposes of this article, I assume that you know something about
PHP, but that's about it. I walk through everything else at an easy pace
— accessing a Foursquare feed, working through the
result set, and cleaning it up. The sample application you build at the
end of the article is simple: provide Foursquare with geolat and geolong coordinates and
see how many people are currently checked in at nearby locations. Because
I live in Austin, Texas, I think it would be interesting to enter
coordinates for a spot on Sixth Street and see what's happening in nearby
places.
I chose this particular option for two reasons. The first is because it's the simplest feed to access, but unwrapping it gives you a pretty good preview of what you can expect with other feeds. The second is that it doesn't require authentication — after all, you're not looking for details on who is actually checked in, just raw counts. The venues public feed provides a great deal of functionality within the scope of this article.
Foursquare is a social location service that allows users to explore the world around them. Users can download the Foursquare application to their iPhone, Blackberry, or Android phone and sign up for free, then connect their Foursquare accounts to their other social media accounts.
After users download the free application and connect on Facebook or Twitter, they can connect with their friends who are also active on Foursquare. Whenever they or their friends check in to a place (that is, they're at a location and they tell others that they are there), the message is broadcast to their friends via Twitter or Facebook.
When a user checks in enough times, that user becomes the mayor of a location, which may or may not give the user access to special offers, depending on the business running a location. For example, a coffee shop might extend a free drink to anyone who becomes a mayor. Users can also earn badges as they explore and check in to locations, leave tips for other users (for instance, "The margaritas here are great!"), and may even have the opportunity to create locations that haven't appeared yet on the service.
Figure 1 is a screenshot of the Foursquare home page on the Web.
Figure 1. Foursquare home page
Foursquare launched its API in November 2009, allowing application developers to extend the platform in interesting ways. Developers can build location management tools, custom search engines, and even games and other tools that interact with the Foursquare API. For example, you could build a geolocation game that allows players to also check in to Foursquare locations as a natural byproduct of normal gameplay.
With this view of Foursquare in mind, let's take a look at the Foursquare API.
A quick tour of the Foursquare API
The Foursquare API allows application developers to interact with the Foursquare platform. The API itself is a RESTful set of addresses to which you can send requests, so there's really nothing to download onto your server. That being said, in this article, you use a set of PHP libraries to help simplify requests and responses, but this is an entirely optional step.
You can currently request output in XML or JSON format, making
requests to URLs that look like this: http://api.foursquare.com/v1/user.json. If you don't use an
extension on your request, then XML is served back to you. A request to
http://api.foursquare.com/v1/user results
in an XML output.
There are both GET and POST methods you can use, which means you
aren't just limited to reading from feeds, you can also do useful stuff
like checking in and creating locations using the API. As for rate
limits, your application is limited to 200 requests per hour per method,
so you probably want to implement some kind of result caching to "play
nice."
For the most part, you want to use basic or OAuth authentication to
take full advantage of the various methods and services. The example in
this article (/venues) doesn't require any
authentication to get started, but it does have additional features
available to those who do use authentication.
What can you do with the API? Table 1 summarizes the major methods. For more details, please read the API documentation (Resources).
Table 1. Summary of Foursquare API methods
| Method | Summary | URL | Parameters | HTTP method(s) | Authentication? |
|---|---|---|---|---|---|
| Checkins | Returns a list of recent check-ins from friends. | http://api.foursquare.com/v1/checkins | geolat, geolong | GET | Yes |
| Checkin | Allows you to check in to a place. | http://api.foursquare.com/v1/checkin | vid, venue, geolat, geolong (others) | POST | Yes |
| History | Returns a list of check-ins for the authenticated user. | http://api.foursquare.com/v1/history | l, sinceid | GET | Yes |
| User detail | Returns profile information for a given user ID. | http://api.foursquare.com/v1/user | uid, twitter, badges, mayor | GET | Yes |
| Friends | Returns a list of friends. | http://api.foursquare.com/v1/friends | uid | GET | Yes |
| Venues | Returns a list of venues near the area specified. | http://api.foursquare.com/v1/venues | geolat, geolong, l, q | GET | No |
| Venue detail | Returns venue data for a given venue ID. | http://api.foursquare.com/v1/venue | vid | GET | No |
| Categories | Returns a hierarchical category list. | http://api.foursquare.com/v1/categories | n/a | GET | No |
| Add venue | Allows you to add a venue. | http://api.foursquare.com/v1/addvenue | name, address, city, state, zip, phone, geolat, geolong, others | POST | Yes |
| Propose venue edit | Allows you to flag a venue for edit or update. | http://api.foursquare.com/v1/venue/proposeedit | vid, name, address, city, state, zip, phone, geolat, geolong, others | POST | Yes |
There are a whole bunch of other API methods that relate to friends, testing authentication, flagging locations for different reasons, gathering and creating tips, etc., but I think you get the general idea.
Building your own PHP application
Now that you've had the nickel tour of the Foursquare API, you can get down to business and build a simple application. As I hinted at in the introduction, what I want to do is create a view that tells me how many people have checked in to locations centered around the Sixth Street bars in Austin. Hey, there's no sense for me driving all the way downtown and finding parking if nobody is actually hanging out down there!
Although it may appear frivolous to use the Foursquare API for this purpose, please note that you can take this basic idea and use it in a variety of contexts. For example, you may want to track how many conference attendees are checking in to local venues while they're in town or how many people are checked in to various conference breakout sessions.
For the purposes of this article, I break the process down into three major pieces:
- Download the helper libraries
- Create a basic feed
- Create a cleaned-up web page with the feed contents
Download the foursquare-async library
Although you really don't need much of a wrapper for the Foursquare API, it's a good idea to download the marvelous foursquare-async library from GitHub (see Resources). It provides a handle of files that let you work with most of the methods available to you via the API.
The download includes a readme file, a license document, and three PHP files:
- EpiCurl.php
- EpiFoursquare.php
- EpiOAuth.php
Put all three PHP files into a directory called lib at the root of your project and move on to the next step in the application construction.
Next, create a file called feed.php and place it in the root of your
project. In this file, you use the require()
function to pull in all the Epi*.php files you downloaded and put in the
lib folder.
Then you instantiate a new epiFourSquare object
and use that object to connect to the venues.json feed, passing in any necessary parameters for
geolat, geolong,
and a limit of 50 results.
Finally, you use json_encode() to transform the
incoming JSON feed into a PHP data object and save it as an array. Of
course, to be safe about all of that, you wrap the whole thing in try {...}exception.
If you don't run the feed through json_encode(),
you end up processing something such as the feed shown below.
Figure 2. Raw JSON feed
This is fine for some people, but you have to admit that the PHP data object shown in Figure 3 is a bit easier to figure out.
Figure 3. PHP data objects from JSON
Listing 1 shows the entire bit of code.
Listing 1. Connecting to the Foursquare venues feed
require('lib/EpiCurl.php');
require('lib/EpiOAuth.php');
require('lib/EpiFoursquare.php');
$fsObj = new EpiFoursquare();
try{
$venues = $fsObj->get_basic('/venues.json',
array('geolat' => '30.268056',
'geolong' => '-97.741381',
'l' => '50'));
$venues_array = json_decode($venues->responseText);
}catch(Exception $e){
echo "Error: ". $e;
}
|
This is nothing terribly complex, just 15 lines of code to get a feed
of venues and check-in counts. Please note that the geolat and geolong coordinates in
the example match the vicinity of the Driskill Hotel in downtown Austin
— I'm using that locale as a convenient central point
because many downtown venues are close to it.
At this point, what you have is a JSON feed that has been converted to a PHP data object. This is useful for the PHP programmer, but nearly useless to anyone else. What you need to do is pull all of this into a web page that mere mortals can use.
To this end, create an index.php file in the root of your directory. Use
any Cascading Style Sheets (CSS) and JavaScript frameworks and design
elements you feel comfortable with. For instance, notice in the sample
code shown in Listing 2 that I use the 960 Grid
framework because it makes my job easy. You also include the feed.php code
you just wrote and then process the $venues_array array so that it fits into a data table.
The complicated bit is that the Foursquare API is hierarchical, with the first level (groups) being pretty meaningless to you. What you need is access to the venues level because that's where you're going to loop through and pull out valuable information for later use.
Part of the example shown in Listing 2 provides you
with a bit of shorthand that does that: foreach
($venues_array->groups[0]->venues as $v){ starts the loop at
the right place in the PHP data object and allows you to access items like
$v->name for venue name and $v->stats->herenow for the number of check-ins
currently at the venue.
In fact, if you visualize the data structure of $v each time through the loop, it looks a bit like Listing 2.
Listing 2. PHP data object for each venue
stdClass Object
{
[id] => 5261
[name] => Driskill Hotel
[primarycategory] => stdClass Object
{
[id] => 79273
[fullpathname] => Travel:Hotel
[nodename] => Hotel
[iconurl] => http://foursquare.com/img/categories/travel/hotel.png
}
[address] => 604 Brazos St
[crossstreet] => at W 6th St
[city] => Austin
[state] => TX
[zip] => 78701
[geolat] => 30.2679601
[geolong] => -97.7413707
[stats] => stdClass Object
{
[herenow] => 0
}
[phone] => 5124745911
[distance] => 0
} |
The code snippet in Listing 3 provides the entire
index.php page, complete with a loop through the data structure, pulling
out the relevant bits to a $final array, which
is then used to create a data table. The result is a dashboard that shows
the name of the venue, its address and phone number, and how many people
are checked in there.
Also, please note that because phone number is not a required field for a venue, you have to run a quick check to see if it's been included in the data feed. If so, print the number; if not, omit it.
Listing 3. Building the index.php view
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>FourSquare API Test</title>
<link rel="stylesheet" type="text/css" href="css/960.css" media="all" />
<link rel="stylesheet" type="text/css" href="css/reset.css" media="all" />
<link rel="stylesheet" type="text/css" href="css/text.css" media="all" />
<link rel="stylesheet" type="text/css" href="css/tables.css" media="all" />
</head>
<body>
<div class="container_12">
<div class="grid_12">
<h1>FourSquare API Test</h1>
</div>
</div>
<div class="container_12">
<div class="grid_12" id="updates">
<?php
include_once 'feed.php';
$final = array();
foreach ($venues_array->groups[0]->venues as $v){
if (isset($v->phone)){
$PHONE = $v->phone;
}else{
$PHONE = "not listed";
}
$final[$v->id] = array(
'name' => $v->name,
'address' => $v->address,
'herenow' => $v->stats->herenow,
'phone' => $PHONE
);
}
?>
<table border='1' cellspacing='0' cellpadding='0'>
<thead>
<tr valign='top'>
<th>Location</th>
<th>Address</th>
<th>Phone</th>
<th>Here Now</th>
</tr>
</thead>
<tbody>
<?php
foreach ($final as $key => $data){
echo "<tr valign='top'>";
echo "<td>".$data['name']."</td>\n";
echo "<td>". $data['address']."</td>\n";
echo "<td>". $data['phone']."</td>\n";
echo "<td align='center'>". $data['herenow']."</td>\n";
echo "</tr>\n";
}
?>
</tbody>
</table>
</div>
</div>
</body>
</html>
|
Most of the code example beyond the PHP is just to make it look good for
people and isn't necessarily functional. You can apply your own styles and
approaches to make the information visually coherent. For example, you can
tie the JSON feed from the PHP file into a jQuery.getJSON() method so it can be refreshed without
having to refresh the Web page.
You can also use a simpler, straightforward list to present the information
so that it appears more natural within the context of a narrow smartphone
screen. For example, Listing 4 shows the final
foreach loop, generating a list.
Listing 4. Simplified listing
?>
<ul>
<?php
foreach ($final as $key => $data){
echo "<li>";
echo $data['name']." (". $data['herenow'].")". "<br/>\n";
echo $data['address']."<br/>\n";
echo $data['phone']."<br/>\n";
echo "</li>\n";
}
?>
</ul>
|
Simply adding a few classes to the UL and LI nodes creates a compelling
visual experience for anyone on an iPhone or other mobile device. They can
check your web page, see what's happening at the locations around the
specific geolat/geolong coordinates, and be able to decide where to go for the
evening.
What else can you do to improve the users' experience? Require a user to
authenticate on Foursquare to see more detail. The details about how to do
this are beyond the scope of this article, but when users are
authenticated, you can deliver even more information about their specific
friends on this list. You can also provide a simple map interface to allow
users to choose a geolat/geolong coordinate to begin with, making this a more generally
useful tool.
Now that you know how to use the Foursquare API, it's your turn to create something interesting. Before you go too deep, though, check out what others are doing with the API. Foursquare's App Gallery contains some notable applications that others have created (see Resources).
Learn
-
Join Foursquare.
-
Read the Foursquare API documentation.
-
Visit Foursquare's App Gallery to see other applications that have been
built with the Foursquare API.
-
PHP.net is the central resource for PHP developers.
-
Check out the "Recommended PHP reading list."
-
Browse all the PHP content on developerWorks.
-
Follow developerWorks on Twitter.
-
Expand your PHP skills by checking out IBM developerWorks' PHP project resources.
-
To listen to interesting interviews and discussions for software developers, check out developerWorks podcasts.
-
Using a database with PHP? Check out the Zend Core for
IBM, a seamless, out-of-the-box, easy-to-install PHP development and production environment that supports IBM DB2 V9.
-
The My developerWorks community is an example of a successful general community that covers a wide variety of topics.
-
Stay current with developerWorks' Technical events and webcasts.
-
Check out upcoming conferences, trade shows, webcasts, and other Events around the world that are of interest to IBM open source developers.
-
Visit the developerWorks Open source zone for extensive how-to information, tools, and project updates to help you develop with open source technologies and use them with IBM's products, as well as our most popular articles and tutorials.
-
Watch and learn about IBM and open source technologies and product functions with the no-cost developerWorks On demand demos.
Get products and technologies
-
Download the foursquare-async
library.
-
Innovate your next open source development project with IBM trial software, available for download or on DVD.
- Download
IBM product evaluation versions
or explore
the online trials in the IBM SOA Sandbox and get your hands on application development tools and middleware products from
DB2®, Lotus®, Rational®, Tivoli®, and WebSphere®.
Discuss
-
Participate in developerWorks blogs and get involved in the developerWorks community.
-
Participate in the developerWorks PHP Forum: Developing PHP applications with IBM Information Management products (DB2, IDS).

Thomas Myer is a consultant, author, and speaker based in Austin. He runs Triple Dog Dare Media and tweets as @myerman on Twitter. You can reach him at tom@tripledogs.com.




