You are hereTech World / IP-to-Country Auto Update

IP-to-Country Auto Update


IP-to-country is a quite useful list of IP ranges provide for free by Webhosting.info. Please check with them about licenses of IP-to-country itself.

Not long ago I realized that forgot to update my IP-to-country list for quite few months. Since I couldn't find a script that would update for me automagically, I decide to build my own.

The biggest challenge is the fact that Webhosting.info keeps the file zipped in the server.

Use at your own risk, there are no warranties.

Some important details:

1) The script was built in a linux server with Apache and PHP;
2) PHP must have able the libraries curl, zip;
3) I used MySQL to maintain my list;
4) Currently, they only update the file once per month thus, it makes no sense to get a new file daily.

My ip_country table has the following fields:
ip_from(double), ip_to(double), iso2(char 2), date_create(datetime), last_update(datetime)

If you have all components running in your web server, all you need to do is adjust the details of the script and to run it in a folder that can write files.

The PHP script:

<?
// IP-to-country auto update
// By Marcelo Paniza
// Use at your own risk, no warranties whatsoever
// where is the zip file?
$url ='http://ip-to-country.webhosting.info/downloads/ip-to-country.csv.zip';

$debug = 1; //=1 turn into debug mode
$userAgent = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648)';
$zname='ip-to-country.csv.zip';
$fname='ip-to-country.csv';
$update='y';

if (file_exists($zname)) {
$difference = abs(strtotime($now) - strtotime(filemtime($zname)));
$days = round((($difference/60)/60)/24,0);

if ($days < 30) {
if ($debug) echo "Only $days day(s) since last update, not going there today";
$update='n';
}
}

if ($update=='y') {
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 300);
curl_setopt($ch, CURLOPT_FILETIME, true);
curl_setopt($ch, CURLOPT_ENCODING, "gzip");
curl_setopt($ch, CURLOPT_HEADER, 0);
// download the zip
$zip = curl_exec($ch);
if (!$zip) { echo "ooooooops couldn't download the zip file"; die; }

// write the zip locally
$fp = fopen($zname, 'w+');
fwrite($fp, $zip);
$size = ftell($fp);
fclose($fp);
echo "Size of Zip is ".$size."
";

// get the csv in the zip
$myzip = zip_open ($zname);
$entry = zip_read ($myzip);
$csv = zip_entry_read($entry, 10000000);
zip_close ($myzip);

// write the zip locally
$fp = fopen($fname, 'w+');
fwrite($fp, $csv);
fclose($fp);

//read the csv line by line
$handle = fopen($fname, "r");
while ($data = fgetcsv($handle, 255, ",")) {
// here is the CSV line by line... insert or update your own DB as you wish
$from = $data[0]; // ip from
$to = $data[1]; // ip to
$c2 = $data[2]; // country 2 chars
$c3 = $data[3]; // country 3 chats
$c4 = $data[4]; // country name
if ($debug) echo "
from:$from -> to:$to -> $c3";

// do I have this range already?
$sql="select ip_from from ip_country where ip_from=$from and ip_to=$to LIMIT 0,1";
$query = mysql_query($sql) or die;
$row = mysql_fetch_array($query);
if (strlen($row[0])>0) {
// yes I do, let's just make sure we know it is updated
$sql="update ip_country set last_update='$now'";
mysql_query($sql) or die;
} else {
// no I don't. Let's insert the new range
$sql="insert into ip_country (ip_from, ip_to, iso2, date_create, last_update) values ($from, $to, '$c2', '$now', '$now')";
mysql_query($sql) or die;
}

}
// now let's delete all the outdate ones
$sql="delete from ip_country where last_update!='$now'";
mysql_query($sql) die;
}
?>