Geo-Targeting PHP Script

August 15th, 2008 → 11:47 am @ Eric Nagel // 33 Comments

I spent a few minutes with Dr_Ngo and Neil Turner at Affiliate Summit, and we were talking about geo-targeting users. Pretty powerful stuff, if your landing page can say, “Find singles in Buffalo, NY” or something similar (whatever your offer is about).

The easy (but ghetto) way to do this to put the city & state in the query string. So it’d be like page.php?city=Buffalo&state=NY. Then in your code, you just echo the city and state variables, like < ?= htmlentities(stripslashes($_GET['city'])) ? >. But what if you just want 1 landing page, without using the query string? It’s actually pretty simple, and I’m going to walk you though it.

So first, you need a database. Here’s a good free one. So from your ssh line, you’ll want to get this database by typing:
wget http://www.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz

Cron this to run monthly (looks like they do updates on the 1st, so run your cron on the 5th or so) and then unzip it:
gunzip GeoLiteCity.dat.gz

OK, now you’re going to want to get the PHP module to use this data. From this directory, download

  • geoip.inc
  • geoipcity.inc
  • geoipregionvars.php

So in a single directory, you’ll have these 3 files and GeoLiteCity.dat. Now you’re about to see how unbelievably easy this script is:

include("geoip.inc");
include("geoipcity.inc");
include("geoipregionvars.php");

$gi = geoip_open("./GeoLiteCity.dat", GEOIP_STANDARD);

$rsGeoData = geoip_record_by_addr($gi, $_SERVER['REMOTE_ADDR']);

echo("<pre>");
print_r($rsGeoData);
echo("</pre>");

geoip_close($gi);

You’ll see I just do a print_r to show all the variables available to you, but for me, I see:

geoiprecord Object
(
[country_code] => US
[country_code3] => USA
[country_name] => United States
[region] => NY
[city] => Buffalo
[postal_code] => 14217
[latitude] => 42.9761
[longitude] => -78.8727
[area_code] => 716
[dma_code] => 514
)

So now your landing page will say,

Find singles in <?= htmlentities($rsGeoData->city . ", " . $rsGeoData->region) ?>

With the latitude & longitude, you can even show a map of the area using the Google Maps API. Having the Zip Code would be great for zip submit offers (only 2 1 left in 14217! – Enter your Zip Code to claim the prize!) or lots of other great ideas using a Zip Code database.

Beware of foreign IPs, though. If you’re not in the US, I don’t know what city or region will give back. You can replace $_SERVER['REMOTE_ADDR'] above with a known IP to see what it returns.

In case you were wondering, I started this installing this script at 3:40 and had it done at 3:50. It took me longer to write this blog post than it did to install the script, so don’t be afraid to try it yourself. If you have problems, though, just contact me.


Tags:

33 Comments → “Geo-Targeting PHP Script”


  1. Ken Savage

    1 year ago

    You must have been thinking the same things I was last weekend. I’m doing the same thing the ghetto way now through my ppc stuff but I’m going to take you up on this script and try that out.

    I am looking to show ads on organic results based on coutry IP later on too but this is a good start. Nice stuff Eric.


  2. Neil

    1 year ago

    Nice! Thanks for script. The zip submit idea is great.


  3. Dave

    1 year ago

    Hey Eric good explanation … I’ve always wondered how to do this. Thanks!


  4. Kevin Carlson

    1 year ago

    Just FYI, some hosting providers have disabled the fopen() function used by geoip_open, for security reasons.
    To make it work, the geoip.inc file would need to be rewritten to use the CURL library instead of fopen().

    I’ve alerted Maxmind to this issue, hopefully they will update their API to address this…

  5. [...] can build an excellent, enterprise-grade Geo-Targeting solution by combining a GeoIP script with the zip/area code database available from [...]

  6. [...] should you buy me a coffee? Maybe you use my RSS -> Deeplink -> Twitter script, or my post on geo-targeting saved you hours of programming, or maybe you use this script that rotates offers based on EPC. [...]


  7. Akram

    1 year ago

    Hi,

    My name is akram. I am software engineer and running my own company named ‘hive’.I am developing a website in which i want to get the country name object, I have redden your post and found very helpful but i could not access the country object please tell me how can i access and country object.


  8. Akram

    1 year ago

    Thanks for your post it is very helpful for me and i get the answer “$rsGeoData->country_name”.

    thanks,
    akram.


  9. Eric

    1 year ago

    As Akram said, $rsGeoData is an object, so you’d access the object variables with ->, like “$rsGeoData->country_name”


  10. garry egan

    1 year ago

    That was an awesome post. Once I found out what this piece was ‘called’ (geotargeting), your site made it easy to deploy.

    Way cool. I think this will most certainly increase conversions…


  11. Al

    1 year ago

    Hey guys….i am an EXTREME newbie to this, but REALLY want to learn it. I did what you said with the three files and the database, and then copied the code intothe page like this:

    include(“geoip.inc”;);
    include(“geoipcity.inc”;);
    include(“geoipregionvars.php”;);

    $gi = geoip_open(“;http://www.hiringcontractorsnow.com/GeoT/GeoLiteCity.dat”;, GEOIP_STANDARD);

    $rsGeoData = geoip_record_by_addr($gi, $_SERVER['REMOTE_ADDR']);

    echo(“;”;);
    print_r($rsGeoData);
    echo(“;”;);

    geoip_close($gi);

    I then copied the bit of code for the city and state like this:

    So now your landing page will say, “Find singles in city . “, ” . $rsGeoData->region) ? >”.

    but i do not get anything that works.

    Can oneof you folks give me a hand?

    Thanks
    AL
    :)


  12. Eric

    1 year ago

    Al – what does print_r($rsGeoData); give you?


  13. Josh

    1 year ago

    I’m a little confused – putting this directly onto a PHP page does not work?

    include(”geoip.inc”);
    include(”geoipcity.inc”);
    include(”geoipregionvars.php”);

    $gi = geoip_open(”./GeoLiteCity.dat”, GEOIP_STANDARD);

    $rsGeoData = geoip_record_by_addr($gi, $_SERVER['REMOTE_ADDR']);

    echo(””);
    print_r($rsGeoData);
    echo(””);

    geoip_close($gi);


  14. Kojak

    11 months ago

    Any demo that already running this geo targetted script?


  15. Eric

    11 months ago

    I don’t have a demo (that I’m going to share), but basically any affiliate dating website will use this. After all, people only want to date others that live around them.


  16. Kojak

    11 months ago

    Hi thanks for the reply eric. I just installed the database earlier which you can see here http://nurseownedbusiness.com/geo/test.php do you know how to change the country abbreviation into full country name? for example:

    US change into United States

    Kojak


  17. Eric

    11 months ago

    Use country_name instead of country_code or country_code3.


  18. Greg

    11 months ago

    just curious – is there any other way to do this? just wondered if you had tinkered with any other methods(?)

    btw, thank you / it works great

    http://www.syrbot.com/tools/geoip/test.php


  19. Eric

    11 months ago

    Greg,

    There’s a Javascript one out there somewhere, but they require a link back to their website. Sorry, but for the life of me, I can’t find it. Besides, you don’t want to link back to someone else :)


  20. Greg

    11 months ago

    please let me know if you remember… i’ll be googl’ing too. thank you!


  21. Cashtactics.net

    11 months ago

    Here is the a javascript version that takes directly from google.


    <script type="text/javascript" src="http://www.google.com/jsapi"> </script>
    <script type="text/javascript">
    if (typeof(google.loader.ClientLocation.address.city) != null) {
    document.write(google.loader.ClientLocation.address.city
    +", "
    +google.loader.ClientLocation.address.region);
    } else {
    document.write("Unknown location")
    }
    </script>


  22. Jerry McKinish

    9 months ago

    I inserted this into the head of my document.

    Then I inserted this into the body of the document. Now My whole page is blank. Can you help?

    <? $gi = geoip_open(“geo/./GeoLiteCity.dat”, GEOIP_STANDARD);

    $rsGeoData = geoip_record_by_addr($gi, $_SERVER['REMOTE_ADDR']);

    echo(””);
    print_r($rsGeoData);
    echo(””);

    geoip_close($gi); ?>

    city . “, ” . $rsGeoData->region) ? >


  23. newbienoob

    9 months ago

    I enter in the following code to my header.php file. I’ve placed all four files into the same directory as my header.php file.

    <?php
    include(“geoip.inc”);
    include(“geoipcity.inc”);
    include(“geoipregionvars.php”);

    $gi = geoip_open(“./GeoLiteCity.dat”, GEOIP_STANDARD);

    $rsGeoData = geoip_record_by_addr($gi, $_SERVER['REMOTE_ADDR']);

    echo(””);
    print_r($rsGeoData);
    echo(””);

    geoip_close($gi);
    ?>

    After placing this into my header and saving it my website shows me a blank page.

    Any suggestions?


  24. Eric

    8 months ago

    Check your quotes – make sure you’re using " and not ”. Sorry, but WordPress puts “smart” quotes in my posts, which PHP does NOT like.


  25. Stephane

    8 months ago

    Hi, this is nice ! My question is : would you know how to get the continent_code ?


  26. Eric

    8 months ago

    @Stephane: – you’ll need an associative array and this data. So you’ll have:

    $rsContinents['US'] = ‘NA’;
    $rsContinents['TN'] = ‘AF’;

    Then you’ll know that if I’m in the US, I’m in NA (North America) and if I’m in TN (Tunisia) I’m in AF (Africa)


  27. Stephane

    8 months ago

    @Eric:
    Ok, I see. But if you use Apache Module (mod_geoip), you can do :

    apache_note(‘GEOIP_CONTINENT_CODE’)

    I was hoping there was such a method like $rsGeoData->continent_code …


  28. chris

    8 months ago

    CashTactics, your javascript works fine! In fact i had been looking for that kind of thing for ages. The method talked about in the post is probably easy too, but
    I didn’t understand a thing. Copy&paste is all my lazy brain can do.

  29. [...] point is to have ammunition when assisting a client with assessing their needs.  Here is a good link if you want to keep tabs on a good thread for how to get started with geo caching. The link is [...]


  30. Mark Heppner

    7 months ago

    This is a great script! I am trying to use it to dynamically change the background and header on my website to match the time of day and weather of the user viewing it. To do this, I’m using XML data called from a weather API such as Yahoo, WeatherBug, or NOAA. However, no services let you call the data by the latitude and longitude. When I test your script, it does not throw back the zip code. It does work and it tells my correct location, but it is just blank for the zip. I need the zip codes to call the weather data! How did you get the zip code database to work? Is it included with the main database? Thanks for any help!


  31. Jehzeel Laurente

    3 months ago

    this is exactly what I need for my US only campaigns. Thank you so much for sharing this! :)

  32. [...] Eric Nagel’s Geo-Targeted PHP script [...]


  33. Soufia

    1 day ago

    thank you / it works great


Leave a Reply