Tempo per una risposta.

IImanuII

Utente Attivo
10 Giu 2012
390
0
16
Salve ragazzi, so che sono un po di giorni che vi rompo le bolas XD ma purtroppo mi vado ad impelagare in situazioni alquanto seccanti :D

Spiego il mio problema:

Ho un sito che gestisce la lingua in base all'ip dell'utente: se l'utente è italiano allora la lingua sarà italiana, se è diversa la lingua allora sarà l'inglese.

Per fare ciò mi sono avvalso di questa funzione

PHP:
<?php
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
  $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
  $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
  $ip = $_SERVER['REMOTE_ADDR'];
}
function ipToCountry($ip){
  $info = file_get_contents("http://who.is/whois-ip/ip-address/$ip");
  list($a, $b) = explode('COUNTRY: ', strtoupper($info));
  return substr(trim($b),0,2);
}

$lingua = strtolower(ipToCountry($ip));


if($lingua == 'it'){

	echo "lingua ita";
}else{

	echo "non ita";
}
?>

Lo script funziona, ma ha alcune evidenti lacune che andrò ad elencare:
1. E' lento nel dare la risposta
2. Oggi è successo che il sito che utilizzo per tracciare l'ip dell'utente http://who.is/whois-ip/ip-address ha avuto qualche problema e praticamente per 20 min non ha più caricato. La cosa si è ripercossa sul mio sito che, non avendo risposta da who.is non caricava affatto. Una volta che ho tolto la funzione scritta su tutto è tornato normale.
3. Inaffidabile.

Onestamente avevo pensato ad alcune soluzioni:
1. Vorrei sapere se è possibile che alcuni "grandi" della rete come Google mettano a disposizione delle api gratuite per il tracciamento dell'ip in modo da far capo a loro.
2. Avevo pensato di dare "un tempo di risposta massimo" entro il quale ricevere la localizzazione dell'utente. Se questa non avviene ad es in un secondo allora riempio la varibile lingua $lingua == 'it', solo che non ho idea di come fare questa cosa, idee?

:rolleyes:
 
Ho provato con quest'altro servizio e pare vada meglio ma vorrei sempre impostare un limite massimo per la risposta e non so come fare.
PHP:
$object = json_decode(file_get_contents("http://ip-api.com/json/$ip"),true);
echo strtolower($object['countryCode']);

Idee?
 
ciao
poi provare a fare una cosa del genere, cioè verificare se il codice lingua viene letto
PHP:
<?php
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
  $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
  $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
  $ip = $_SERVER['REMOTE_ADDR'];
}
function ipToCountry($ip){
	//messo il silent @ davanti a file_get_contents per non visualizzare l'errore
	//messo wh al posto di who per simulare l'errore (cioè non legge)
	if(@file_get_contents("http://wh.is/whois-ip/ip-address/$ip")===FALSE){//qui simulo l'errore
		return 'ERRORE';//oppure return 'it';
	}else{
		$info = file_get_contents("http://who.is/whois-ip/ip-address/$ip");
  		list($a, $b) = explode('COUNTRY: ', strtoupper($info));
  		return strtolower(substr(trim($b),0,2));
	}
}

$lingua = ipToCountry($ip);
var_dump($lingua);
?>
ho modificato il tuo primo script ma è adattabile anche per il secondo
 
Ciao, io propongo una soluzione piu semplice :
La variabile "HTTP_ACCEPT_LANGUAGE" ti restituisce la lingua del browser ( o del S.O. non ricordo)
PHP:
if (substr($_SERVER["HTTP_ACCEPT_LANGUAGE"], 0, 2) == "it") {
    echo "Italiano";
} else {
    echo "Inglese";
}
 
Grazie borgo dopo lo provo. Secondo te in termini di economicità di tempo e quindi anche di risorse, quali tra i due script è meglio? Io oserei il json_decode

@glm si si lo so sono impaziente e me ne scuso :D

Edit: se il sito non va giù ma è solo lentissimo a dare una risposta lo script da te modificato non ho ben capito come si comporta: aperta comunque una risposta o dopo tipo 2 sec passa oltre?

Edit2: @criric. Avevo pensato anche io ad una soluzione del genere ma molte persone in Italia hanno il browser in inglese perché magari è impostato così quando gli arriva il PC e non sanno cambiarlo. Avevo una soluzione del genere prima ma non andava, poiché quando viene rilevata una lingua non italiana la fanpage a cui gli utenti hanno la possibilità di mettere mi piace cambia. Rilevando la lingua del browser mi sono accorto che avevo molti italiani all'interno della pagina internazionale di facebook. Così invece sono molti di meno.

Inviato dal mio Nexus 4 con Tapatalk
 
Ultima modifica:
ciao criric
del bw, però ha un piccolo difetto se l'utente è italiano e ha il bw settato a inglese il sito si presenta in lingia inglese e non è detto che all'utente piaccia leggere un testo in inglese
sarà ma io sono convinto che i classici bottoncini can le bandiere sia il sistema più comodo, al massimo usare i cokie per far in modo che per quell'utente si apra sampre nella lingua da lui scelta

edit
... sito non va giù .... o dopo tipo 2 sec passa oltre?
no solo se non risponde, non so ma credo che per fare quello che vuoi forse devi usare qualcosa lato client

poi non so dirti se quello con json sia meglio, penso che dipenda dal servizio
 
Ultima modifica:
In realtà sarebbe la soluzione ideale borgo, ma il mio è un blog e non prevede utenti registrati. Al massimo dovrei comunque tracciare l'ip utente e a quel punto assegnargli un cookie, ma se traccio l'IP mi conviene settare direttamente la lingua no? Comunque, per caso conoscete una qualche funzione di PHP che mi consenta di impostare un timeout? Nel senso che se la risposta es. It non mi arriva entro 3 secondi la variabile viene riempita con il valore da me scelto. Ora sono da telefono e non posso cercare ma se non ricordo male (nelle api di facebook avevo visto sto comando) doveva esserci qualcosa come CONNECTION_TIMEOUT o una cosa simile, vi risulta?

Inviato dal mio Nexus 4 con Tapatalk
 
ciao
puoi provare questo, ma non so dirti se funziona, anche perche testarla non è semplice
PHP:
<?php
function ipToCountry($ip){
	$inizio=time();//leggo il tempo di partenza
    if(@file_get_contents("http://who.is/whois-ip/ip-address/$ip")===FALSE){//qui simulo l'errore
        while(time() < ($inizio+5)){//continuo a leggere il tempo ad ogni ciclo
			return ipToCountry($ip); //richiamo ricorsivamente la funzione
		}
		return 'ERRORE';//oppure return 'it';
    }else{
        $info = file_get_contents("http://who.is/whois-ip/ip-address/$ip");
          list($a, $b) = explode('COUNTRY: ', strtoupper($info));
          return strtolower(substr(trim($b),0,2));
    }
}
?>
tra l'altro non so in termini di prestazioni cosa può succedere

poi che gli utenti sia registrati o no non c'entra nulla con i cookie.
se l'utente non sceglie la lingua setti il cookie a IT, altrimenti lo setti alla lingua scelta
 
Ho trovato il comando a cui mi riferivo curlopt_connecttimeout.
Ma purtroppo va con il curl, non è che mi conviene utilizzarlo invece del json?
 
ciao
puoi provare questo, ma non so dirti se funziona, anche perche testarla non è semplice
PHP:
<?php
function ipToCountry($ip){
	$inizio=time();//leggo il tempo di partenza
    if(@file_get_contents("http://who.is/whois-ip/ip-address/$ip")===FALSE){//qui simulo l'errore
        while(time() < ($inizio+5)){//continuo a leggere il tempo ad ogni ciclo
			return ipToCountry($ip); //richiamo ricorsivamente la funzione
		}
		return 'ERRORE';//oppure return 'it';
    }else{
        $info = file_get_contents("http://who.is/whois-ip/ip-address/$ip");
          list($a, $b) = explode('COUNTRY: ', strtoupper($info));
          return strtolower(substr(trim($b),0,2));
    }
}
?>
tra l'altro non so in termini di prestazioni cosa può succedere

poi che gli utenti sia registrati o no non c'entra nulla con i cookie.
se l'utente non sceglie la lingua setti il cookie a IT, altrimenti lo setti alla lingua scelta

Non c'è un errore di logica nella funzione borgo? Nel momento in cui if(@file_get_contents("http://who.is/whois-ip/ip-address/$ip")===FALSE){ rilevo già che il sito non è raggiungile, quindi mi risulta essere inutile confrontareil tempo. Credo piuttosto che bisognerebbe provare a inserirlo nella seconda condizione dopo l'else no? O ho detto una cazzata?
 
ciao
non dovrebbe, anche se come detto non so come funziona, ma il principio e questo se il sito che ti da la lingua è lento
1) cerca di leggere e non riesce
2) se non sono passati 5 secondi legge di nuovo e verifica (richiama se stessa)
3)se letto esce e da la lingua se non letto rilegge
e così via per 5 secondi se dopo 5 sec non è riusita ancora a leggere esce definitivamente con errorre (o it)
comunque in effetti c'è un errore, nella lettura del tempo iniziale che deve essere fuori della funzione (altrimenti si aggiorna ogni volta) e passato alla funzione come riferimento o usando global
 
Ho fatto in questo modo e sembra, ripeto SEMBRA funzionare:

PHP:
<?php
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
  $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
  $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
  $ip = $_SERVER['REMOTE_ADDR'];
}

function ipToCountry($ip){
	$t = microtime() - $tempo;
    if(@file_get_contents("http://ip-api.com/json/$ip")===FALSE || $t>1){//qui simulo l'errore 
        return 'ERRORE';//oppure return 'it'; 
    }else{ 
		$object = json_decode(file_get_contents("http://ip-api.com/json/$ip"),true);
		return strtolower($object['countryCode']);
    } 
} 

$lingua = ipToCountry($ip); 
var_dump($lingua); 

?>
<!-- stampa del tempo di generazione della pagina -->	
<br /><center><?php $t = microtime() - $tempo;   echo "This page was generated by server in $t seconds"; ?></center>

Secondo voi è corretta come soluzione?
 
Dovrebbe funzionare ma c'era un errore:

Il tempo di generazione della pagina ovviamente non è lo stesso della tempo di generazione dell'informazione. Per vedere la differenza ho modificato così:

PHP:
<?php
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
  $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
  $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
  $ip = $_SERVER['REMOTE_ADDR'];
}

function ipToCountry($ip){
	$t = microtime() - $tempo;
    if(@file_get_contents("http://ip-api.com/json/$ip")===FALSE /*|| $t>1*/){//qui simulo l'errore 
        return 'ERRORE';//oppure return 'it'; 
    }else{ 
		$object = json_decode(file_get_contents("http://ip-api.com/json/$ip"),true);
		return strtolower($object['countryCode'])."  $t";
    } 
} 

$lingua = ipToCountry($ip); 
var_dump($lingua); 

?>
<!-- stampa del tempo di generazione della pagina -->	
<br /><center><?php $t = microtime() - $tempo;   echo "This page was generated by server in $t seconds"; ?></center>

Che dite secondo voi va bene?
 
Utilizza $_SERVER['HTTP_ACCEPT_LANGUAGE'] se ti serve solo la nazionalità sennò online trovi molte api gratuite

esempio
PHP:
function ipInfo($ip)
{
  $ch = curl_init('http://freegeoip.net/json/'.$ip);
  curl_setopt_array($ch, array(CURLOPT_RETURNTRANSFER => true));
  return json_decode(curl_exec($ch));
}

echo ipInfo($_SERVER['REMOTE_ADDR'])->country_name;
 
Perdonatemi ma non posso editare, dopo qualche minuto mi impedisce la modifica. Comunque il codice corretto è questo

PHP:
<?php
$tempo=microtime(true);
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
  $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
  $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
  $ip = $_SERVER['REMOTE_ADDR'];
}

function ipToCountry($ip){
	$t = microtime();
    if(@file_get_contents("http://ip-api.com/json/$ip")===FALSE || $t>1){
        return 'ERRORE  $t';//oppure return 'it';
    }else{
		$object = json_decode(file_get_contents("http://ip-api.com/json/$ip"),true);
		return strtolower($object['countryCode'])."  $t";
    }
}

$lingua = ipToCountry($ip); 
var_dump($lingua); 

?>
<!-- stampa del tempo di generazione della pagina -->	
<br /><center><?php $t = microtime(true) - $tempo;   echo "This page was generated by server in $t seconds"; ?></center>

Dite che va bene oppure ho commesso qualche errore di logica? La funzione microtime è adeguata?
 
Propongo un altra alternativa
L'ho testato online e sembrerebbe funzionare.
Giusto per dare più scelta anche a chi leggerà in futuro, voi fate come volete :fonzie:
 
Propongo un altra alternativa
L'ho testato online e sembrerebbe funzionare.
Giusto per dare più scelta anche a chi leggerà in futuro, voi fate come volete :fonzie:

E' un'ottima alternativa anche questa soprattutto perché non hai dipendenze esterne. Se non erro è possibile anche non scaricare il db contenente i paesi visto che sono interessato solo all'Italia giusto?
 
Si credo ti basti scaricare solo quelli che contengono ip italiani, fai qualche prova e facci sapere
 

Discussioni simili