Ok, Leute, danke für eure Vorschläge; Während ich mehr als 6.000 IPs habe, sind einige Dienste aufgrund einiger Einschränkungen bei meinen Anforderungen fehlgeschlagen. Sie können sie also alle im Fallback-Modus verwenden.
Wenn wir eine Quelldatei mit folgendem Format haben:
user_id_1 ip_1
user_id_2 ip_2
user_id_3 ip_1
als Sie diesen einfachen Expample-Befehl (PoC) für Yii verwenden könnten:
class GeoIPCommand extends CConsoleCommand
{
public function actionIndex($filename = null)
{
//http://freegeoip.net/json/{$ip} //10k requests per hour
//http://ipinfo.io/{$ip}/json //1k per day
//http://ip-api.com/json/{$ip}?fields=country,city,regionName,status //150 per minute
echo "start".PHP_EOL;
$handle = fopen($filename, "r");
$destination = './good_locations.txt';
$bad = './failed_locations.txt';
$badIP = [];
$goodIP = [];
$destHandle = fopen($destination, 'a+');
$badHandle = fopen($bad, 'a+');
if ($handle)
{
while (($line = fgets($handle)) !== false)
{
$result = preg_match('#(\d+)\s+(\d+\.\d+\.\d+\.\d+)#', $line, $id_ip);
if(!$result) continue;
$id = $id_ip[1];
$ip = $id_ip[2];
$ok = false;
if(isset($badIP[$ip]))
{
fputs($badHandle, sprintf('%u %s'. PHP_EOL, $id, $ip));
continue;
}
if(isset($goodIP[$ip]))
{
fputs($destHandle, sprintf('"id":"%u","ip":"%s","from":"%s";'. PHP_EOL, $id, $ip, $goodIP[$ip]));
echo sprintf('"id":"%s","ip":"%s","from":"%s";'. PHP_EOL, $id, $ip, $goodIP[$ip]);
continue;
}
$query = @json_decode(file_get_contents('http://freegeoip.net/json/'.$ip));
$city = property_exists($query, 'region_name')? $query->region_name : '';
$city .= property_exists($query, 'city') && $query->city && ($query->city != $city) ? ', ' . $query->city : '';
if($city)
{
fputs($destHandle, sprintf('"id":"%u","ip":"%s","from":"%s";'. PHP_EOL, $id, $ip, $city));
echo sprintf('"id":"%s","ip":"%s","from":"%s";'. PHP_EOL, $id, $ip, $city);
$ok = true;
}
if(!$ok)
{
$query = @json_decode(file_get_contents('http://ip-api.com/json/'. $ip.'?fields=country,city,regionName,status'));
if($query && $query->status == 'success')
{
$city = property_exists($query, 'regionName')? $query->regionName : '';
$city .= property_exists($query, 'city') && $query->city ? ',' . $query->city : '';
if($city)
{
fputs($destHandle, sprintf('"id":"%u","ip":"%s","from":"%s";'. PHP_EOL, $id, $ip, $city));
echo sprintf('"id":"%s","ip":"%s","from":"%s";'. PHP_EOL, $id, $ip, $city);
$ok = true;
}
}
}
if(!$ok)
{
$badIP[$ip] = false;
fputs($badHandle, sprintf('%u %s'. PHP_EOL, $id, $ip));
echo sprintf('"id":"%s","ip":"%s","from":"%s";'. PHP_EOL, $id, $ip, 'Unknown');
}
if($ok)
{
$goodIP[$ip] = $city;
}
}
fclose($handle);
fclose($badHandle);
fclose($destHandle);
}else{
echo 'Can\'t open file' . PHP_EOL;
return;
}
return;
}
}
Dies ist eine Art Shitty-Code, aber es funktioniert. Verwendung:
./yiic geoip index --filename="./source_id_ip_list.txt"
Fühlen Sie sich frei, es zu verwenden, zu modifizieren und es besser zu machen)