• Home

Logo

Navigation
  • Home
  • Articles
    • Content Writing
    • Design
    • General
    • Internet Marketing
    • Social Media
    • Tools and Tips
    • Usability
    • Web Hosting Articles
  • Tutorials
    • AJAX Tutorials
    • ASP Tutorials
    • C# Tutorials
    • CGI and Perl Tutorials
    • CSS Tutorials
    • Flash Tutorials
    • HTML Tutorials
    • Illustrator Tutorials
    • Java Tutorials
    • JavaScript Tutorials
    • Linux Tutorials
    • Miscellaneous Tutorials
    • MySQL Tutorials
    • Photoshop Tutorials
    • PHP Tutorials
    • Python Tutorials
    • Wireless Tutorials
    • WordPress Tutorials
    • XML Tutorials
  • Scripts
    • AJAX Scripts
    • ASP Scripts
    • ASP.NET Scripts
    • CGI & Perl Scripts
    • Flash Scripts
    • Java Scripts
    • JavaScript Scripts
    • PHP Scripts
    • Python Scripts
    • Remotely Hosted
    • Tools and Utilities
    • XML Scripts
  • Answers
  • Online Services
  • Tools

Effective Geotargeting with PHP

By Akash Mehta | on Jan 27, 2008 | 1 Comment
PHP Tutorials
  • Tweet
  • Share
  • Tweet
  • Share

Introduction

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
require_once 'geoip.inc';
$gi = geoip_open( 'GeoIP.dat', GEOIP_STANDARD );
$country = geoip_country_code_by_addr( $gi, $_SERVER['REMOTE_ADDR'] );
echo $country;
?>

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 PEAR

We’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
require_once "Net/GeoIP.php";
$geoip = Net_GeoIP::getInstance("/path/to/geoip.dat");
try {
echo $geoip->lookupCountryCode($_SERVER['REMOTE_ADDR']);
} catch (Exception $e) {
// Handle exception
}

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 considerations

Let us take a look at our original code snippet:

  <?php
require_once 'geoip.inc';
$gi = geoip_open( 'GeoIP.dat', GEOIP_STANDARD );
$country = geoip_country_code_by_addr( $gi, $_SERVER['REMOTE_ADDR'] );
echo $country;
?>

All very well; nice and simple. But is it really? What’s going on behind the scenes with geoip_open() and geoip_country_code_by_addr()?
If we do a quick benchmark, on a standard shared web host this script
takes on average 0.05 seconds to execute. Now, that might not seem like
a lot, but consider that on average an entire script to generate a
database-driven page takes 0.01 seconds on the same server. With just
20 hits per second, your new GeoIP script could slow your server to a
crawl, not to mention the processing required by the rest of your
website. Given this, you definitely want to be caching your lookup,
possibly in session data.

Visuals

Of 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 system

Given 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
session_start();

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'])) {
require_once 'geoip.inc';
$gi = geoip_open( 'GeoIP.dat', GEOIP_STANDARD );
$country = geoip_country_code_by_addr( $gi,
$_SERVER['REMOTE_ADDR'] );
$_SESSION['geocountry'] = $country;
}

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']);
echo '<img src="flags/png/'.$country.'.png" />';

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.

Share this story:
  • tweet

Author Description

One Response to “Effective Geotargeting with PHP”

  1. September 28, 2010

    derekbennett Log in to Reply

    I have searched far and wide for a geo-targeting method that suited my needs. Basically I needed to do a handful of things:

    1) Forward to another URL based on city/region/country/etc
    2) Get the latitude and longitude of the detected city
    3) Be extremely fast
    4) Determine the closest major city

    I cooked up my own solution to handle the first 3. I used MaxMind’s free GeoIP database (which is fairly accurate). This worked fine, but I didnt like that it was displaying whatever tiny town was detected. If a user saw the small town, they would instantly know they’re being tricked. I wanted to say “Ok find the closest city with a population of over 2000000 people and display it”. After a while I finally found Lambda GeoIP which I liked for a few reasons:

    -Free updates for life (to both the script and the database
    -Lots of examples and functions to make using it super easy
    -The nearest major city feature

    But there were also one thing I didnt like about it

    -No Javascript built in, so if you needed to use it in javascript you’d have to code something up to pull from the script first.

    Overall, though, I like it and still use it. A lot of people make silly mistakes when doing geo-targeting, you just gotta be clever. If you use geo-targeting correctly its a huge benefit.

You must be logged in to post a comment.

Connect With Us

RSSSubscribe 1,242Followers 492Likes
  • Popular
  • Recent
  • Comments
  • Creating Energy Spheres in Photoshop

    Apr 15, 2008 - 96 Comments
  • Easy Screen Scraping in PHP with the Simple HTML DOM Library

    Aug 6, 2008 - 20 Comments
  • Calculating date difference more precisely in PHP

    Mar 7, 2008 - 13 Comments
  • When Does Hosting Your Website in the Cloud Make Sense?

    Oct 8, 2010 - 2 Comments
  • Fun with the Microsoft Managed Extensibility Framework Part 2

    Oct 6, 2010 - 0 Comment
  • Fun with the Microsoft Managed Extensibility Framework Part 1

    Sep 22, 2010 - 0 Comment
  • Website Management on the go with the iPad

    I appreciated your post, but I was looking for something I didn't...
    November 24, 2012 - drmoderator
  • Creating Energy Spheres in Photoshop

    I'm a little stuck down here especially at the step of creating the...
    November 23, 2012 - sarah
  • Running background processes in PHP

    Can you give an example? As see it, you can use this only when you...
    November 16, 2012 - Shaked Klein Orbach
Developer Resources
  • Tutorial Directory
  • Learn HTML
  • Learn PHP
  • Learn CSS
  • Learn AJAX
  • Learn JavaScript
  • Learn Pear
  • White Papers
  • Resources
    • NetVisits Web Directory
    • Realtor Pixels
    • Answers On The Run
    • Ask A Geek
  • Recent Posts

    • When Does Hosting Your Website in the Cloud Make Sense?
    • Fun with the Microsoft Managed Extensibility Framework Part 2
    • Fun with the Microsoft Managed Extensibility Framework Part 1
    • Website Management on the go with the iPad
    • Code Contracts in C# 4.0 – Part 1

    Calendar

    May 2013
    M T W T F S S
    « Oct    
     12345
    6789101112
    13141516171819
    20212223242526
    2728293031  

    Recent Comments

    • drmoderator on Website Management on the go with the iPad
    • sarah on Creating Energy Spheres in Photoshop
    • Shaked Klein Orbach on Running background processes in PHP
    • Thomas Cuvillier on How To Upload Files Using PHP
    • rizal aditya on Extracting text from Word Documents via PHP and COM
    • Home
    © 2003 - 2013 DeveloperTutorials.com. All Rights Reserved. Privacy Policy.