Ver Mensaje Individual
  #6 (permalink)  
Antiguo 13/02/2011, 18:44
Avatar de Italico76
Italico76
 
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años, 8 meses
Puntos: 292
Respuesta: [APORTE] clase de GeoLocalizacion

DEMO: http://www.betadir.com/clases/geo.class.php

Ultima actualizacion incluye un metodo para re-seleccionar base de datos si habia una previa seleccionada: close()

Tengan en cuenta que el nombre de la DB de geolocalizacion esta dentro de la clase misma y Uds deberian cambiarlo.

Código PHP:
<?php
include "my/config.php";

class 
Geo {
  private 
$con;    
  public  
$selected;
  private 
$localhost;
  private 
$data = array(
                   
// DB DATA
                  
'host','user','pass',  
           
// GEO 
                  
'ip'=>null'locId'=>null,'country'=>null,'region'=>null,'city'=>null,
                  
'postalCode'=>null,'latitude'=>null,'longitude'=>null,
          
'metroCode'=>null,'areaCode'=>null,
          
'countryName'=>null,'lan'=>null);
           
    
  public function 
Geo(){    
  }  
    
  public function 
__set($name$value) {
      
//echo "Estableciendo '$name' a '$value'\n";
      
$this->data[$name] = $value;
  }

  public function 
__get($name) {
      
//echo "Consultando '$name'\n";
      
if (array_key_exists($name$this->data)) {
          return 
$this->data[$name];
      }

        
      
$trace debug_backtrace();
      
trigger_error(
          
'Propiedad indefinida mediante __get(): ' $name .
          
' en ' $trace[0]['file'] .
          
' en la línea ' $trace[0]['line'],
          
E_USER_NOTICE);
      return 
null;
  }

  
/**  Desde PHP 5.1.0  */
  
public function __isset($name) {
      
//echo "¿Está definido '$name'?\n";
      
return isset($this->data[$name]);
  }

  
/**  Desde PHP 5.1.0  */
  
public function __unset($name) {
      
//echo "Eliminando '$name'\n";
      
unset($this->data[$name]);
  }
    
      
  private function 
connect(){  
   
$this->con    mysql_connect($this->host,$this->user,$this->pass) or die ("Error conectando a mysql en {$_SERVER['PHP_SELF']}");   
     
   
$res mysql_query("SELECT DATABASE()");
   if (
mysql_num_rows($res)==1){
     
$row mysql_fetch_array ($res);
     
$this->selected $row[0];      
   }   
   
   
mysql_select_db('videosbu_geo') or die ("Error seleccionando base en {$_SERVER['PHP_SELF']}"); 
  }  
    
  public function 
close(){     
     if ( (isset(
$this->selected)) AND (!$this->localhost) ){
       
mysql_select_db($this->selected) or die ("Error seleccionando base en {$_SERVER['PHP_SELF']}");   
     }  
  }     
    
  public function 
IPremote(){
    
$this->ip =  $_SERVER['REMOTE_ADDR'];    
  }
  
  public function 
doit($also_lan_and_countryName=true){
  
    if (
$this->ip == '127.0.0.1'){
      
$this->data['country']='xx';
      
$this->data['countryName']='localhost';
      
$this->data['city']='localhost';
      
$this->localhost true;
      
      return 
true;
      
// fin del flujo       
    
}    
  
    
$this->connect();    
    
$ipv4 toIPv4($this->ip);
    
    
$sql  "
    SELECT cl.country, cl.region, cl.city, cl.postalCode, cl.latitude, cl.longitude, cl.metroCode, cl.areaCode FROM citylocation cl 
    INNER JOIN 
    (SELECT locId FROM cityblocks WHERE  ($ipv4 > startIpNum AND $ipv4 < endIpNum) ORDER BY startIpNum DESC LIMIT 1) 
    t1 ON cl.locid = t1.locId"
;    
    
$res       mysql_query($sql) OR die(mysql_error());
    
$cant_rows mysql_num_rows($res);
    
    if (
$cant_rows==1){
      
$this->data mysql_fetch_assoc($res);        

      if (
$also_lan_and_countryName){ 
        
// recupero nombre de pais y lengua 
        
$sql "SELECT lan,name FROM countries WHERE id='{$this->country}'";
        
$res mysql_query($sql) OR die(mysql_error());
        
$row mysql_fetch_array($res);      
      
        
$this->lan $row['lan'];
        
$this->countryName $row['name'];
      }
      
      
// retorno exito
      
return true;
    }else{
      
// no hay resultados
      
return false
    }    
       
  }
  
  
// end class
  

function toIPv4 ($dotted){
  if (( 
$lngIP ip2long $dotted)) < ){ 
    
$lngIP += 4294967296 ;
  }
  return 
$lngIP;
}


function 
set_geo_vars(){
  
session_start();  
  global 
$db_info;  
  
  
// pregunto si ya busque geolocalizacion para no repetir la busqueda en la DB
  
if (!isset($_SESSION['geo_runned'])){
  
    
$loc= new geo();
    
$loc->host  $db_info['host'];
    
$loc->user  $db_info['user'];
    
$loc->pass  $db_info['pass'];
    
$loc->IPremote();  
    
$succ $loc->doit();
    
$loc->close();  // devuelve a la DB antes seleccionada (si la hay)

    
$_SESSION['geo_runned']     = 1;
  
    if (
$succ){      
      
$_SESSION['country']      = $loc->country;
      
$_SESSION['countryname']  = $loc->countryName;
      
$_SESSION['city']         = $loc->city;
      
$_SESSION['latitude']     = $loc->latitude;
      
$_SESSION['longitude']    = $loc->longitude;
      
$_SESSION['lan_from_geo'] = $loc->lan;
    }else{
       return 
false;
      
//echo 'No se encontro info para esa IP';
    
}  
  }     
    return 
true
}

?>
La funcion set_geo_vars() la utilizo para dejar como variables de session los datos de geolocalizacion y evitar calcularlos antes y despues de que un usuario se registre. Al menos, yo necesite eso.

Tablas:

Cita:
CREATE TABLE IF NOT EXISTS `cityblocks` (
`startIpNum` bigint(20) NOT NULL,
`endIpNum` bigint(20) NOT NULL,
`locId` bigint(20) NOT NULL,
PRIMARY KEY (`startIpNum`),
UNIQUE KEY `locId` (`startIpNum`,`endIpNum`,`locId`),
KEY `endIpNum` (`endIpNum`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS `citylocation` (
`locId` bigint(20) NOT NULL,
`country` varchar(2) NOT NULL,
`region` varchar(2) NOT NULL,
`city` varchar(50) NOT NULL,
`postalCode` varchar(10) NOT NULL,
`latitude` int(11) NOT NULL,
`longitude` int(11) NOT NULL,
`metroCode` int(11) NOT NULL,
`areaCode` int(11) NOT NULL,
PRIMARY KEY (`locId`),
UNIQUE KEY `locId` (`locId`,`country`,`region`,`city`,`postalCode`,`l atitude`,`longitude`,`metroCode`,`areaCode`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Para utilizarla es asi:

Código PHP:
<?php
Include "geo.class.php"// tu path

$loc= new geo();
$loc->host  $db_info['host'];
$loc->user  $db_info['user'];
$loc->pass  $db_info['pass'];
//$loc->IPremote();
$loc->ip '148.210.232.247';
$succ $loc->doit();

if (
$succ){
  echo 
"Codigo de pais: ".$loc->country.'<br/>';
  echo 
"Nombre de pais: ".$loc->countryName.'<br/>';
  echo 
"Ciudad: ".$loc->city.'<br/>';
  echo 
"Latitud: ".$loc->latitude.'<br/>';
  echo 
"Longitud: ".$loc->longitude.'<br/>';  
  echo 
"Lengua oficial: ".$loc->lan.'<br/>';
  
}else{
 echo 
'No se encontro info para esa IP';

?>
Un abrazo y recuerden de la DEMO
__________________
Salu2!

Última edición por Italico76; 17/02/2011 a las 05:47