自分のIPアドレスから訪問者の市、州、国などの情報を取得し、自分のWebページをその場所に応じてカスタマイズできるようにします。 PHPでこれを行うための良い信頼できる方法はありますか?クライアントサイドのスクリプト作成にはJavaScript、サーバーサイドのスクリプト作成にはPHP、データベースにはMySQLを使用しています。
無料のGeoIPデータベースをダウンロードしてIPアドレスをローカルで検索することも、サードパーティのサービスを使用してリモート検索を実行することもできます。これはセットアップを必要としないためより単純なオプションですが、追加の待ち時間が発生します。
あなたが使うことができる一つの第三者サービスは私のものです http://ipinfo.io 。それらは、ホスト名、位置情報、ネットワーク所有者、および追加情報を提供します。
$ curl ipinfo.io/8.8.8.8
{
"ip": "8.8.8.8",
"hostname": "google-public-dns-a.google.com",
"loc": "37.385999999999996,-122.0838",
"org": "AS15169 Google Inc.",
"city": "Mountain View",
"region": "CA",
"country": "US",
"phone": 650
}
これがPHPの例です。
$ip = $_SERVER['REMOTE_ADDR'];
$details = json_decode(file_get_contents("http://ipinfo.io/{$ip}/json"));
echo $details->city; // -> "Mountain View"
クライアントサイドでも使えます。これが簡単なjQueryの例です。
$.get("https://ipinfo.io/json", function (response) {
$("#ip").html("IP: " + response.ip);
$("#address").html("Location: " + response.city + ", " + response.region);
$("#details").html(JSON.stringify(response, null, 4));
}, "jsonp");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h3>Client side IP geolocation using <a href="http://ipinfo.io">ipinfo.io</a></h3>
<hr/>
<div id="ip"></div>
<div id="address"></div>
<hr/>Full response: <pre id="details"></pre>
誰もこの特定のAPIに関する情報を提供していないように私は投稿したいと思いましたが、それは私の後に正確に戻ってきて、あなたはそれを複数のフォーマットで返すように取得できます、json, xml and csv
。
$location = file_get_contents('http://freegeoip.net/json/'.$_SERVER['REMOTE_ADDR']);
print_r($location);
これはあなたが望むかもしれないことすべてをあなたに与えるでしょう:
{
"ip": "77.99.179.98",
"country_code": "GB",
"country_name": "United Kingdom",
"region_code": "H9",
"region_name": "London, City of",
"city": "London",
"zipcode": "",
"latitude": 51.5142,
"longitude": -0.0931,
"metro_code": "",
"areacode": ""
}
Google APISを使用する
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script>
contry_code = google.loader.ClientLocation.address.country_code
city = google.loader.ClientLocation.address.city
region = google.loader.ClientLocation.address.region
</script>
http://www.hostip.info/ のような外部サービスを使用する必要があります。 "geo-ip"をGoogleで検索した場合、より多くの結果を得ることができます。
Host-IP APIはHTTPベースであるため、ニーズに応じてPHPまたはJavaScriptのいずれかで使用できます。
私は ipapi.co からAPIを使ってボットを書きました、これがphp
でIPアドレス(例えば1.2.3.4
)の位置を取得する方法です:
ヘッダを設定します。
$opts = array('http'=>array('method'=>"GET", 'header'=>"User-Agent: mybot.v0.7.1"));
$context = stream_context_create($opts);
JSONレスポンスを受け取る
echo file_get_contents('https://ipapi.co/1.2.3.4/json/', false, $context);
特定のフィールド(国、タイムゾーンなど)を取得する
echo file_get_contents('https://ipapi.co/1.2.3.4/country/', false, $context);
純粋なJavascriptの例では、 https://geoip-db.com のサービスを使用しています。これらはJSONおよびJSONPコールバックソリューションを提供します。
JQueryは必要ありません。
<!DOCTYPE html>
<html>
<head>
<title>Geo City Locator by geoip-db.com</title>
</head>
<body>
<div>Country: <span id="country"></span></div>
<div>State: <span id="state"></span></div>
<div>City: <span id="city"></span></div>
<div>Postal: <span id="postal"></span></div>
<div>Latitude: <span id="latitude"></span></div>
<div>Longitude: <span id="longitude"></span></div>
<div>IP address: <span id="ipv4"></span></div>
</body>
<script>
var country = document.getElementById('country');
var state = document.getElementById('state');
var city = document.getElementById('city');
var postal = document.getElementById('postal');
var latitude = document.getElementById('latitude');
var longitude = document.getElementById('longitude');
var ip = document.getElementById('ipv4');
function callback(data)
{
country.innerHTML = data.country_name;
state.innerHTML = data.state;
city.innerHTML = data.city;
postal.innerHTML = data.postal;
latitude.innerHTML = data.latitude;
longitude.innerHTML = data.longitude;
ip.innerHTML = data.IPv4;
}
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://geoip-db.com/json/geoip.php?jsonp=callback';
var h = document.getElementsByTagName('script')[0];
h.parentNode.insertBefore(script, h);
</script>
</html>
この質問は保護されています、私は理解しています。しかし、私はここで答えを見ません、私が見るのは同じ質問をすることから彼らが思いついたことを示している多くの人々です。
現在、IP所有権に関する最初の窓口として機能する、機能の程度が異なる5つの地域インターネットレジストリがあります。このプロセスは流動的です。そのため、ここでのさまざまなサービスは時々機能し、他の時には機能しません。
だれが(明らかに)古代のTCPプロトコルであるか - それがもともと働いていた方法はポート43への接続によるものでした、それはそれがリースを通した接続、ファイアウォールなどを通してルーティングされるのを難しくします。
現時点では - ほとんどの人はRESTful HTTPとARINを介して行われ、RIPEとAPNICはRESTfulなサービスを提供しています。 LACNICは503を返し、AfriNICはそのようなAPIを持っていないようです。 (ただし、すべてオンラインサービスがあります。)
それはあなたを - IPの登録所有者のアドレス - あなたをつかむでしょう - しかしあなたのクライアントの場所ではありません - あなたは彼らからそれを得なければなりません - そしてまたあなたはそれを尋ねなければなりません。また、プロキシは、あなたが発信者であると思うIPを検証するときのあなたの悩みのうちで最も少ないものです。
人々は彼らが追跡されているという概念を理解していないので、私の考えはそうです - あなたのクライアントから直接そして彼らの許可を得てそれを入手して、その概念に反論することをたくさん期待しています。
Hostip.infoからのAPIを見てください - それはたくさんの情報を提供します。
PHPでの例:
$data = file_get_contents("http://api.hostip.info/country.php?ip=12.215.42.19");
//$data contains: "US"
$data = file_get_contents("http://api.hostip.info/?ip=12.215.42.19");
//$data contains: XML with country, lat, long, city, etc...
あなたがhostip.infoを信頼するのであれば、それは非常に便利なAPIのようです。
私は同じ答えをするつもりです ここ サービスはPHPでも利用可能です。
私は無料の GeoLite City をMaxmindから提供しています。これはほとんどのアプリケーションで動作し、有料版にアップグレードできます。他の言語と同様に、 PHP API が含まれています。 LighttpdをWebサーバーとして実行している場合は、 module を使用して、訪問者ごとにSERVER変数の情報を取得することもできます。
無料の Geolite Country (IPの出身地を正確に特定する必要がない場合はもっと速いでしょう)とGeolite ASN(あなたがIPを所有している人を知りたい場合)も追加する必要があります。そして最後にこれらはすべてあなた自身のサーバーにダウンロード可能で、毎月更新され、 "毎秒何千ものルックアップ"を述べているので提供されたAPIを使ってルックアップするのはとても速いです。
PHPには 拡張子が付いています。
PHP.netから:
GeoIP拡張機能を使用すると、IPアドレスの場所を見つけることができます。市、州、国、経度、緯度、およびISPや接続タイプなどのその他すべての情報は、GeoIPを使用して取得できます。
例えば:
$record = geoip_record_by_name($ip);
echo $record['city'];
あなたが自分でやりたいと思って他のプロバイダに頼らないと仮定すると、 IP2Nation は地域レジストリが状況を変えるにつれて更新されるマッピングのMySQLデータベースを提供します。
Ben Dowlingの回答の中のサービスが変更されたので、今はもっと簡単になっています。場所を見つけるには、単純に次のようにします。
// no need to pass ip any longer; ipinfo grabs the ip of the person requesting
$details = json_decode(file_get_contents("http://ipinfo.io/"));
echo $details->city; // city
座標は '31、-80'のような単一の文字列で返されます。
$coordinates = explode(",", $details->loc); // -> '31,-89' becomes'31','-80'
echo $coordinates[0]; // latitude
echo $coordinates[1]; // longitude
Ipdata.co は、信頼性の高いパフォーマンスを備えた高速で可用性の高いIP Geolocation APIです。
世界中に10のエンドポイントがあり、それぞれ1秒あたり10,000を超える要求を処理できるという点で、非常にスケーラブルです。
この回答では、「テスト」APIキーを使用していますが、これは非常に限られており、ほんの数回の呼び出しをテストするためのものです。 サインアップ あなた自身の無料APIキーのために開発のために毎日1500の要求まで得てください。
Phpで
php > $ip = '8.8.8.8';
php > $details = json_decode(file_get_contents("https://api.ipdata.co/{$ip}?api-key=test"));
php > echo $details->region;
California
php > echo $details->city;
Mountain View
php > echo $details->country_name;
United States
php > echo $details->latitude;
37.751
これは、国、地域、市を取得する方法を示すクライアント側の例です。
$.get("https://api.ipdata.co?api-key=test", function (response) {
$("#response").html(JSON.stringify(response, null, 4));
$("#country").html('Country: ' + response.country_name);
$("#region").html('Region ' + response.region);
$("#city").html('City' + response.city);
}, "jsonp");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="country"></div>
<div id="region"></div>
<div id="city"></div>
<pre id="response"></pre>
免責事項;
私はサービスを構築しました。
複数の言語での例については、 Docs を参照してください。
this 最良のIP位置情報APIの詳細な分析もご覧ください。
誰かがこのスレッドにつまずいた場合は、別の解決策があります。 timezoneapi.io あなたはIPアドレスを要求し、見返りにいくつかのオブジェクトを取得することができます(私はサービスを作成しました)。これは、ユーザーがどのタイムゾーンにいたのか、世界のどこにいるのか、そして現在の時間帯を知る必要があるために作成されました。
In PHP - 場所、タイムゾーン、および日付/時刻を返します。
// Get IP address
$ip_address = getenv('HTTP_CLIENT_IP') ?: getenv('HTTP_X_FORWARDED_FOR') ?: getenv('HTTP_X_FORWARDED') ?: getenv('HTTP_FORWARDED_FOR') ?: getenv('HTTP_FORWARDED') ?: getenv('REMOTE_ADDR');
// Get JSON object
$jsondata = file_get_contents("http://timezoneapi.io/api/ip/?" . $ip_address);
// Decode
$data = json_decode($jsondata, true);
// Request OK?
if($data['meta']['code'] == '200'){
// Example: Get the city parameter
echo "City: " . $data['data']['city'] . "<br>";
// Example: Get the users time
echo "Time: " . $data['data']['datetime']['date_time_txt'] . "<br>";
}
JQueryを使う:
// Get JSON object
$.getJSON('https://timezoneapi.io/api/ip', function(data){
// Request OK?
if(data.meta.code == '200'){
// Log
console.log(data);
// Example: Get the city parameter
var city = data.data.city;
alert(city);
// Example: Get the users time
var time = data.data.datetime.date_time_txt;
alert(time);
}
});
私は IPLocate.io でサービスを実行しています。
<?php
$res = file_get_contents('https://www.iplocate.io/api/lookup/8.8.8.8');
$res = json_decode($res);
echo $res->country; // United States
echo $res->continent; // North America
echo $res->latitude; // 37.751
echo $res->longitude; // -97.822
var_dump($res);
$res
オブジェクトには、country
、city
などの地理位置情報フィールドが含まれます。
詳しくは docs をご覧ください。
以下は、情報を取得するために http://ipinfodb.com/ip_locator.php を使用していることがわかったスニペットの修正版です。覚えておいてください、あなたは彼らと一緒にAPIキーを申請し、あなたが適切と思うように供給された情報を得るために直接APIを使うこともできます。
function detect_location($ip=NULL, $asArray=FALSE) {
if (empty($ip)) {
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']; }
}
elseif (!is_string($ip) || strlen($ip) < 1 || $ip == '127.0.0.1' || $ip == 'localhost') {
$ip = '8.8.8.8';
}
$url = 'http://ipinfodb.com/ip_locator.php?ip=' . urlencode($ip);
$i = 0; $content; $curl_info;
while (empty($content) && $i < 5) {
$ch = curl_init();
$curl_opt = array(
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_HEADER => 0,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $url,
CURLOPT_TIMEOUT => 1,
CURLOPT_REFERER => 'http://' . $_SERVER['HTTP_Host'],
);
if (isset($_SERVER['HTTP_USER_AGENT'])) $curl_opt[CURLOPT_USERAGENT] = $_SERVER['HTTP_USER_AGENT'];
curl_setopt_array($ch, $curl_opt);
$content = curl_exec($ch);
if (!is_null($curl_info)) $curl_info = curl_getinfo($ch);
curl_close($ch);
}
$araResp = array();
if (preg_match('{<li>City : ([^<]*)</li>}i', $content, $regs)) $araResp['city'] = trim($regs[1]);
if (preg_match('{<li>State/Province : ([^<]*)</li>}i', $content, $regs)) $araResp['state'] = trim($regs[1]);
if (preg_match('{<li>Country : ([^<]*)}i', $content, $regs)) $araResp['country'] = trim($regs[1]);
if (preg_match('{<li>Zip or postal code : ([^<]*)</li>}i', $content, $regs)) $araResp['Zip'] = trim($regs[1]);
if (preg_match('{<li>Latitude : ([^<]*)</li>}i', $content, $regs)) $araResp['latitude'] = trim($regs[1]);
if (preg_match('{<li>Longitude : ([^<]*)</li>}i', $content, $regs)) $araResp['longitude'] = trim($regs[1]);
if (preg_match('{<li>Timezone : ([^<]*)</li>}i', $content, $regs)) $araResp['timezone'] = trim($regs[1]);
if (preg_match('{<li>Hostname : ([^<]*)</li>}i', $content, $regs)) $araResp['hostname'] = trim($regs[1]);
$strResp = ($araResp['city'] != '' && $araResp['state'] != '') ? ($araResp['city'] . ', ' . $araResp['state']) : 'UNKNOWN';
return $asArray ? $araResp : $strResp;
}
detect_location();
// returns "CITY, STATE" based on user IP
detect_location('xxx.xxx.xxx.xxx');
// returns "CITY, STATE" based on IP you provide
detect_location(NULL, TRUE); // based on user IP
// returns array(8) { ["city"] => "CITY", ["state"] => "STATE", ["country"] => "US", ["Zip"] => "xxxxx", ["latitude"] => "xx.xxxxxx", ["longitude"] => "-xx.xxxxxx", ["timezone"] => "-07:00", ["hostname"] => "xx-xx-xx-xx.Host.name.net" }
detect_location('xxx.xxx.xxx.xxx', TRUE); // based on IP you provide
// returns array(8) { ["city"] => "CITY", ["state"] => "STATE", ["country"] => "US", ["Zip"] => "xxxxx", ["latitude"] => "xx.xxxxxx", ["longitude"] => "-xx.xxxxxx", ["timezone"] => "-07:00", ["hostname"] => "xx-xx-xx-xx.Host.name.net" }
IPアドレスから位置情報を取得する必要がある場合は、信頼できるgeo ipサービスを使用できます。詳細については、 を参照してください 。 IPv6に対応しています。
ボーナスとして、それはIPアドレスがTorノード、パブリックプロキシ、またはスパマーであるかどうかをチェックすることを可能にします。
下記のようにjavascriptまたはphpを使用できます。
Javascriptコード:
$(document).ready(function () {
$('#btnGetIpDetail').click(function () {
if ($('#txtIP').val() == '') {
alert('IP address is reqired');
return false;
}
$.getJSON("http://ip-api.io/json/" + $('#txtIP').val(),
function (result) {
alert('City Name: ' + result.city)
console.log(result);
});
});
});
PHPコード:
$result = json_decode(file_get_contents('http://ip-api.io/json/64.30.228.118'));
var_dump($result);
出力:
{
"ip": "64.30.228.118",
"country_code": "US",
"country_name": "United States",
"region_code": "FL",
"region_name": "Florida",
"city": "Fort Lauderdale",
"Zip_code": "33309",
"time_zone": "America/New_York",
"latitude": 26.1882,
"longitude": -80.1711,
"metro_code": 528,
"suspicious_factors": {
"is_proxy": false,
"is_tor_node": false,
"is_spam": false,
"is_suspicious": false
}
私が作成した ipinfo.ioのラッパー 。あなたはcomposerを使ってそれをインストールすることができます。
あなたはこのようにそれを使うことができます:
$ipInfo = new DavidePastore\Ipinfo\Ipinfo();
//Get all the properties
$Host = $ipInfo->getFullIpDetails("8.8.8.8");
//Read all the properties
$city = $Host->getCity();
$country = $Host->getCountry();
$hostname = $Host->getHostname();
$ip = $Host->getIp();
$loc = $Host->getLoc();
$org = $Host->getOrg();
$phone = $Host->getPhone();
$region = $Host->getRegion();
私はIPアドレスサービスでたくさんのテストをしました、そして、ここで私が自分でそれをするいくつかの方法があります。まず、私が使用している便利なWebサイトへのリンクをまとめます。
https://db-ip.com/db 無料のip-lookupサービスがあり、いくつかの無料のcsvファイルをダウンロードできます。これはあなたのEメールに添付されている無料のAPIキーを使用します。 1日あたり2000クエリに制限されています。
http://ipinfo.io/ APIキーなしの無料のIP検索サービスPHP機能:
//uses http://ipinfo.io/.
function ip_visitor_country($ip){
$ip_data_in = get_web_page("http://ipinfo.io/".$ip."/json"); //add the ip to the url and retrieve the json data
$ip_data = json_decode($ip_data_in['content'],true); //json_decode it for php use
//this ip-lookup service returns 404 if the ip is invalid/not found so return false if this is the case.
if(empty($ip_data) || $ip_data_in['httpcode'] == 404){
return false;
}else{
return $ip_data;
}
}
function get_web_page($url){
$user_agent = 'Mozilla/5.0 (Windows NT 6.1; rv:8.0) Gecko/20100101 Firefox/8.0';
$options = array(
CURLOPT_CUSTOMREQUEST =>"GET", //set request type post or get
CURLOPT_POST =>false, //set to GET
CURLOPT_USERAGENT => $user_agent, //set user agent
CURLOPT_RETURNTRANSFER => true, // return web page
CURLOPT_HEADER => false, // don't return headers
CURLOPT_FOLLOWLOCATION => true, // follow redirects
CURLOPT_ENCODING => "", // handle all encodings
CURLOPT_AUTOREFERER => true, // set referer on redirect
CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
CURLOPT_TIMEOUT => 120, // timeout on response
CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
);
$ch = curl_init( $url );
curl_setopt_array( $ch, $options );
$content = curl_exec( $ch );
$err = curl_errno( $ch );
$errmsg = curl_error( $ch );
$header = curl_getinfo( $ch );
$httpCode = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
curl_close( $ch );
$header['errno'] = $err; //curl error code
$header['errmsg'] = $errmsg; //curl error message
$header['content'] = $content; //the webpage result (In this case the ip data in json array form)
$header['httpcode'] = $httpCode; //the webpage response code
return $header; //return the collected data and response codes
}
最後にあなたはこのようなものを手に入れます:
Array
(
[ip] => 1.1.1.1
[hostname] => No Hostname
[city] =>
[country] => AU
[loc] => -27.0000,133.0000
[org] => AS15169 Google Inc.
)
http://www.geoplugin.com/ やや古くなっていますが、このサービスでは、国外通貨、大陸のコード、経度などの便利な情報を多数提供しています。
http://lite.ip2location.com/database-ip-country-region-city-latitude-longitude データベースにそれらをインポートするための指示を含むダウンロード可能なファイルの束を提供します。データベースにこれらのファイルから1つを作成したら、かなり簡単にデータを選択できます。
SELECT * FROM `ip2location_db5` WHERE IP > ip_from AND IP < ip_to
Php関数ip2long()を使用してください。 IPアドレスを数値に変換します。たとえば、1.1.1.1は16843009になります。これにより、データベースファイルによって指定されたIP範囲をスキャンできます。
だから1.1.1.1がどこに属しているのかを知るためにこのクエリを実行してください。
SELECT * FROM `ip2location_db5` WHERE 16843009 > ip_from AND 16843009 < ip_to;
例としてこのデータを返します。
FROM: 16843008
TO: 16843263
Country code: AU
Country: Australia
Region: Queensland
City: Brisbane
Latitude: -27.46794
Longitude: 153.02809
"smart-ip"サービスを使うこともできます。
$.getJSON("http://smart-ip.net/geoip-json?callback=?",
function (data) {
alert(data.countryName);
alert(data.city);
}
);
更新された/正確なデータベースを探しているなら、私はこれを使うことをお勧めします ここ それは私がテストしたとき他の多くのサービスに含まれていなかった私の正確な位置を示していました。
(私がテストしていたとき、私の市はRasht
、私の国はIran
で、このIPアドレスは2.187.21.235
でした。)
APIメソッドよりもデータベースを使用することをお勧めします。ローカルでの処理がはるかに高速になるためです。
私は数か月前にこの記事を書きましたが、あなたに役立つかもしれません。この記事では、ip 2国のオープンソースデータベースの使い方と、そのオープンソースデータベースを機能させるために私が書いたphpクラスについても説明しています。これがリンクです
http://www.samundra.com.np/find-visitors-country-using-his-ip-address/1018
これに関して何か助けが必要な場合は、私のコメントをサイトにドロップしてください。
お役に立てば幸いです。
IPジオロケーションを実行するには、2つの広範なアプローチがあります。1つは、データセットをダウンロードし、インフラストラクチャでホストして、最新の状態に維持することです。特に、多数のリクエストをサポートする必要がある場合、これには時間と労力が必要です。もう1つの解決策は、すべての作業を管理する既存のAPIサービスを使用することです。
多くのAPI Geolocationサービスがあります:Maxmind、Ip2location、Ipstack、IpInfoなど。最近、私が働いている会社はIpregistry( https://ipregistry.co )そして、私は決定と実装のプロセスに関与していました。 IPジオロケーションAPIを探す際に考慮する必要がある要素を次に示します。
IPジオロケーション情報を取得する例を次に示します(1回の呼び出しで脅威とユーザーエージェントのデータも取得します)。
$ip = $_SERVER['REMOTE_ADDR'];
$details = json_decode(file_get_contents("https://api.ipregistry.co/{$ip}?key=tryout"));
echo $details->location;
注:私はここでIpregistryを宣伝するのではなく、最高だと言いますが、既存のソリューションを分析するのに長い時間を費やし、そのソリューションは本当に有望です。
さて、皆さん、あなたの提案をありがとう。私は6k +のIPを持っていますが、いくつかのサービスはいくつかの制限のために私の要求に失敗します。そのため、それらすべてをフォールバックモードで使用できます。
次の形式のソースファイルがあるとします。
user_id_1 ip_1
user_id_2 ip_2
user_id_3 ip_1
あなたがYiiのためにこの簡単なexpampleコマンド(PoC)を使うことができるより:
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;
}
}
これはある種のくだらないコードですが、うまくいきます。使用法:
./yiic geoip index --filename="./source_id_ip_list.txt"
気軽に使って、修正して、うまくやろう)