I got kind of bored today and after I've noticed a lot of people worried about Yahoo banning them becuase of non-us visitors I've decided to do something about it. I've written a function that reads the GeoIP CVS file (available free of charge at http://www.maxmind.com/app/geoip_country ) and imports into a database table only certain countries or just one. Countries can be specified easily using their 2-letter country code. For example, United States and Canada are specificed using this string : "us,ca" There are two more functions available: IPFromCountry ($country , $ip="" ) The function takes the IP and checks if it is in the database created before and if it belongs to the country specified by $country. Example ipfromcountry("us","216.9.35.50"); returns 1 ( unless digitalpoint is not in US ) ) If IP is not specified the PHP file attempts to detect the visitor's IP and uses that IP. Example ipfromcountry("us") return 1 or 0 depending on the visitors location and if that location is not in the database, it return 0; IPInDB Takes the visitor's IP and checks if that IP is in the database, no matter what country. Returns 1 if there is inside , 0 otherwise. PHP Example of implementation : 1. Create the GeoIP table in database, with only IP from United States inside: <? require_once("geoip.php"); // geoip.php is the name of my code $count = importgeoip(); ?> PHP: 2. Detect if a certain IP belongs to United States <? require_once("geoip.php"); // geoip.php is the name of my code if (ipfromcountry("us","216.9.35.50")==1) { print "The IP is in United States"; } if (ipfromcountry("us")==1) { print "<br> I'm showing you this because you're in United States"; } ?> PHP: 3. Detect if the visitor is in one of the coutries in database <? require_once("geoip.php"); // geoip.php is the name of my code if (ipindb()==1) { print "Good country, IP in database"; } ?> [/php] Here's the full code to the geoip.php file I've written. The code is also available in zip format here : http://www.helpedia.com/geoip.zip <? $mysql_host="localhost"; $mysql_username="root"; $mysql_password="password"; // >> CHANGE << $mysql_defaultdb="database"; // >> CHANGE << $mysql_table="table"; // >> CHANGE (if needed) << $filename = "GeoIPCountryWhois.csv"; $geoip_countries = "us"; // list of countries to be added, can use comma ex: "us,ca" // // Escape values sent to MySQL // function sqlesc($x) { $value = $x; // Stripslashes if (get_magic_quotes_gpc()) { $value = stripslashes($value); } // Quote if not integer if (!is_numeric($value)) { $value = "'" . mysql_real_escape_string($value) . "'"; } return $value; } // Connect to server, select database function db_connect($database="") { global $mysql_host; global $mysql_username; global $mysql_password; global $mysql_defaultdb; $error_message = "<center>Sorry, it seems there was an error connecting to the database server. The reason is listed below:<br><br><strong>%err%</strong></center>"; $connection = @mysql_connect($mysql_host,$mysql_username, $mysql_password); if (!$connection ) { die (str_replace("%err%",mysql_error(),$error_message)); } if ( $database != "") { $db = $database; } else { $db = $mysql_defaultdb; } mysql_select_db($db) or die(str_replace("%err%",mysql_error(),$error_message)); return $connection; } // // IP Validation // function validip($ip) { if (!empty($ip) && ip2long($ip)!=-1) { // reserved IANA IPv4 addresses http://www.iana.org/assignments/ipv4-address-space $reserved_ips = array ( array('0.0.0.0','2.255.255.255'), array('10.0.0.0','10.255.255.255'), array('127.0.0.0','127.255.255.255'), array('169.254.0.0','169.254.255.255'), array('172.16.0.0','172.31.255.255'), array('192.0.2.0','192.0.2.255'), array('192.168.0.0','192.168.255.255'), array('255.255.255.0','255.255.255.255') ); foreach ($reserved_ips as $r) { $min = ip2long($r[0]); $max = ip2long($r[1]); if ((ip2long($ip) >= $min) && (ip2long($ip) <= $max)) return false; } return true; } else return false; } // // Function to detect the IP of the person accesing the page // function getip() { global $HTTP_SERVER_VARS; if (validip($HTTP_SERVER_VARS['HTTP_CLIENT_IP'])) return $HTTP_SERVER_VARS['HTTP_CLIENT_IP']; elseif ($HTTP_SERVER_VARS['HTTP_X_FORWARDED_FOR']!="") { $forwarded=str_replace(",","",$HTTP_SERVER_VARS['HTTP_X_FORWARDED_FOR']); $forwarded_array=split(" ",$forwarded); foreach($forwarded_array as $value) if (validip($value)) return $value; } return $HTTP_SERVER_VARS['REMOTE_ADDR']; } // This function imports certain countries from the GeoIP into the database // // Returns : // // -1 : CVS file not found on the server // -2 : Can not drop table // -3 : Can not create table // -4 : Insert record into database error // +0 : Any positive number, the number of records inserted // function ImportGeoIP() { global $filename; global $mysql_table; global $geoip_countries; $fhandle = fopen($filename,"r"); if (!$fhandle) { return -1; } fclose($fhandle); $lines = file($filename); $conn = db_connect(); $query = mysql_query("DROP TABLE IF EXISTS ".$mysql_table,$conn); if (!$query) return -2; $query = mysql_query("CREATE TABLE ".$mysql_table." (ipstart int(11) NOT NULL default '0', ipend int(11) NOT NULL default '0', cc char(2) NOT NULL default '') ENGINE=MyISAM",$conn); if (!$query) return -3; $count =0; foreach ($lines as $line_num => $line) { $s = $line; $s = strtolower(str_replace("\"","",$s)); $values = explode(",",$s); $valuesaregood=1; if (is_numeric($values[2])==false) $valuesaregood=0; if (is_numeric($values[3])==false) $valuesaregood=0; if (stristr($geoip_countries,$values[4])==false) $valuesaregood=0; if ($valuesaregood==1) { $query = mysql_query("INSERT INTO `".$mysql_table."` (`ipstart`, `ipend`, `cc`) VALUES (".sqlesc($values[2]).", ".sqlesc($values[3]).", ".sqlesc(trim($values[4])).")",$conn); if (!$query) return -4; $count = $count +1; } } mysql_close($conn); return $count; } // This function takes the 2-letter country and an IP (optional) as parameters // // If IP is not specified the function attempts to detect the IP of the person accessing the page // // Returns 1 if IP belongs to country specified and if country listed in database // Returns 0 if country not in database or IP does not belong to country or if error occurs // function ipfromcountry($country,$ip="") { global $mysql_table; $theip= trim($ip); if ($theip=="") $theip=getip(); // if ip not specified, get the default ip user has if ($theip=="") return 0; // could not detect ip, assume not in country. $iplong = ip2long($theip); $conn = db_connect(); $query = mysql_query("SELECT `cc` FROM ".$mysql_table." WHERE ipstart<= ".$iplong." AND ipend >= ".$iplong,$conn); if (!query) return 0; // error in query, assume not in country $object = mysql_fetch_object($query); mysql_close($conn); if (strtolower($country)==$object->cc) return 1; return 0; } // // This function takes the IP of the person reading the page and checks if it is between the countries // listed in the table. Returns 1 if true, 0 otherwise // function ipindb() { global $mysql_table; $theip= getip(); // if ip not specified, get the default ip user has if ($theip=="") return 0; // could not detect ip, assume not in country. $iplong = ip2long($theip); $conn = db_connect(); $query = mysql_query("SELECT `cc` FROM ".$mysql_table." WHERE ipstart<= ".$iplong." AND ipend >= ".$iplong,$conn); if (!query) return 0; // error in query, assume not in country if (mysql_num_rows($query)>0) return 1; mysql_close($conn); return 0; } PHP: Final Notes : The functions will fail if there are no records in table, therefore only the first time you use this, you must use ImportGeoIP You should upload the CVS file once a week in the folder where geoip.php resides and run ImportGeoIP, in order to keep its accuracy. The free GeoIP CVS is updated by MaxMind once a week and estimates it is 97% accurate. It is usually enough. For more accuracy, you may have to purchase it. I hope it is of use to you.