Show Yahoo Ads Based On Visitor Country

Discussion in 'PHP' started by mariush, Mar 5, 2006.

  1. #1
    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.
     
    mariush, Mar 5, 2006 IP
    vishwaa likes this.