Effective Geotargeting with PHPby: Akash MehtaIntroduction In this tutorial, we'll take a look at the technique of geotargeting,
or serving content to users based on their physical location. The
technology is invaluable; with simple techniques, you can target
advertising to specific users, collect more accurate usage statistics,
serve content in different languages for different regions and provide
local information like weather reports to your visitors. I'll briefly
cover what you need to know about geoip, and then move on to some code
samples of how to achieve it with the Maxmind database, using both the
standard PHP library and the PEAR version.IP Targeting: It’s tricky business! For geo location, the IP address of your users is probably the most useful piee of information. The IP address of a user can be matched against a database of current IP allocations globally to work out where the user is based; the trouble is maintaining an up-to-date database of the current IP allocations. Economies of scale kick in at a point, and a company called MaxMind manage to offer some pretty accurate geolocation technology entirely free of charge. If you're interested in the technical details, they have a detailed explanation of the IP location process on their website. Their database is so popular that there's even a PEAR package to suit, although MaxMind provide their own pure PHP library and PECL extension — we'll cover both pure PHP versions in this tutorial. Getting started The database is the key to all our GeoIP work — the better the database, the more accurate the country check. The free database from MaxMind offers “Over 98%” accuracy, which is pretty good, but a 2% failure rate can be a little high for businesses. We'll stick to the free version for the moment; you can grab a copy here — you'll need the “latest GeoLite Country Binary Format” version. You'll also need to get their PHP library here. Finally, download and install the PEAR package, Net_GeoIP — you can do this via command line or grab the package file here. Access to a PHP webserver is assumed. Of course, there's no need to try out these samples; the code is pretty light-weight so you can follow along without testing it out. Incidentally, if you want to write your own lookup system, a CSV version of the actual IP database is available that is very easy to work with when imported into a SQL database. Bear in mind, however, that the database is very large, and another lookup to a database table for every single user can cause significant server load. Let's write some code! Once you've got the library and the database — throw them all into the same folder for simplicity — it's actually pretty easy. Load up your favourite text editor and type this in: <?php This presumes you've put both the geoip.inc library and geoip.dat database in the same folder. $_SERVER['REMOTE_ADDR'] should represent your IP address. If you're behind a proxy or firewall this could be somewhat inaccurate and possibly even a little misleading, but generally this should work fine. You won't get much luck running this on your local machine, as your IP would be a wonderfully non-descriptive 127.0.0.1; you'll have to upload it to a remote server to see the results. You should see a very short country code; a couple of letters, nothing else. For example, here's my result: AU That may not look like much, but it's not just any country code: it's your country code. In four lines of code we've worked out a standard country code corresponding to your location — and imagine the possibilities with that! Of course, there's much more we can do. From here, experiment with serving special content to particular countries and having friends abroad try to visit the page. A touch of PEARWe're all for code re-use here, so let's take a look at the PEAR version. Just a brief intro: PEAR is a repository of PHP libraries all built in approximately the same somewhat predictable manner. They are designed to be highly reusable, making them fantastic for completing projects in short timeframes, and help you avoid reinventing the wheel. But PEAR isn't just about libraries; it's a fully-fledged package distribution system that probably came installed with your version of PHP, as well as a community creating and supporting all this great work. See pear.php.net for more info. The PEAR version works in much the same way, only has improved PHP 5 style error handling and is a little more clear. Here's how to do it with the PEAR library: <?php Notice here we can natively catch any errors that occur; in the older version, we had to test if no value was returned. The PEAR version is not necessarily more reliable at conducting lookups — it's using the same database — but it will be a little easier to work with if you've used PEAR packages before, and it also makes use of some useful PHP 5 features. I recommend using the PEAR version, but it's up to you and for basic use won't make much of a difference. For high traffic sites with basic geolocation needs, you might find that the original version offers better performance as it doesn't come with the overhead of an object. Performance considerationsLet us take a look at our original code snippet: <?php All very well; nice and simple. But is it really? What's going on behind the scenes with VisualsOf course, this country code isn't of much use on its own anyway — so how about we make it a little more useful to your users? Show them a small version of their country's flag to invoke the patriot inside anyone! From Mark James, of Silk icon set fame, comes a fantastic library of 247 flags for just about every country out there. What's more, they're small, totally free, look good on any web page and follow the same naming conventions as your PHP routine. Just drop them in place, lowercase your country codes and show the appropriate flag to easily impress any user. A complete geotargeting systemGiven these performance considerations and the visuals possible with the flag icons, let's create a simple geotargeting system that you can drop in to your website. First, we initialise: <?php Note that including our geoip.inc library is in itself overhead we would like to avoid where performance is an issue. As a result, we deal with it later instead. We need our script to save the user's country in the session and show a nice little PNG of the country's flag. So, we first test if the session data isn't there, and set it accordingly using our script from above: if (!isset($_SESSION['geocountry'])) {
On subsequent page loads, the 'geocountry' session variable would already have been set by this snippet; it essentially serves as a user-based cache, and we leave the tricky session handling to PHP (although you may want to use your own session library as part of a framework). Next, we display the PNG flag: $country = strtolower($_SESSION['geocountry']); Now, load the script up in your web browser. With any luck you should see something like the following:
It may seem rather small, but it's actually the perfect size for fitting into a content-rich web page, and works quite nicely inside navigation bars and menu sections of any size. It's also very recognisable to the user as their flag, and finally, after all the pretty visuals are dealt with, we now have the user's country available for use in our session's 'geocountry' variable. Tips and tricks Typically automatic language selection was very tricky, as browsers often weren't setup properly to tell the server what languages the end user expected. The remedy was to ask the user directly, but a long list of languages was very daunting for the end-user, and leaving some minority languages out was potentially insulting. With geolocation, you could combine the user's country with a database of locales based on country, then default to one but offer a clear choice of two or three (as appropriate) for the user to choose from; problem solved. Content delivery networks also use geotargeting a lot. The idea of a content delivery network is that servers located physically closer to the user often incurred lower data transfer costs and were somewhat quicker, an important factor in winning users. With geotargeting, for example, all images from a site can be fed off a local server. Alternatively, you could redirect the user to the local version of your website altogether, possibly even on an entirely new domain. Say your domain was example.com, you might want to redirect me to example.com.au, where your local site is not only quicker to load, but has better targeted content and more relevant ads as well. Going further We aren't limited by country codes, of course — if you take a look through the documentation for the PEAR package, you'll find methods for country name, region and even organization / ISP! Experiment with multiple versions of your website content in a format that you can easily work with; if you have a content management system, you may be able to build a feature to create pages for users from a particular country. If you're looking for slightly more accurate lookups, MaxMind also offers city databases that complement the country database we worked with in this tutorial, and they have paid versions of both that offer somewhat better accuracy. Be creative and have fun guiding your users to a new world, where the information knows just a little more about them. © 2008 NetVisits, Inc. All rights reserved. |