IPアドレスから場所を取得する


205

訪問者の市、州、国などの情報をIPアドレスから取得して、場所に応じてWebページをカスタマイズできるようにしたいと考えています。PHPでこれを行うための良い信頼できる方法はありますか?クライアント側のスクリプトにはJavaScript、サーバー側のスクリプトにはPHP、データベースにはMySQLを使用しています。


回答:


255

無料のGeoIPデータベースをダウンロードしてローカルでIPアドレスを検索するか、サードパーティのサービスを使用してリモート検索を実行できます。セットアップが不要なため、これはより簡単なオプションですが、レイテンシが増加します。

使用できるサードパーティのサービスの1つは、私の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>


1
URLの最後にjsonを追加して、Webページ全体ではなくjsonを確実に取得できるようにすることをお勧めします。$ details = json_decode(file_get_contents( " ipinfo.io {$ ip} / json"));
ダグ

1
@Manataxそうではありません。サーバーの応答を解析することが不可能になるからです。
ジャック

3
とても信頼できるサービスではないようです。私はnull私の都市名を得ています。それは小さな都市や何かのようではありませんが、それでもそれを見つけることができませんでした。米国内でうまく機能しない場合、米国外でもnullが返される頻度は疑問です。
Derek款會功夫2014年

2
結果は正確ではありません..地域、市の郵便
マークゲリルミランディージャ

2
警告:2019年1月の時点で、トロイの木馬が原因で、このipinfo URLがvirustotalに対して安全ではないという報告がありました。投票は2015年から2018年の間でした
Ricardo

55

この特定の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": ""

}

1
Hey Jamie FreegeoIp.netが機能していません。他に方法はありますか?
Adi

申し訳ありませんが、ライブサイトで使用しているサービスは残念です。彼らが
いつか

2
ほとんどダウンしていて、めったに地域や都市を与えない
Rahul aman

2
AzureでのTonyのサービスは高速かつ確実に機能しているようです:freegeoip2
Gustav

1
「このAPIエンドポイントが廃止され、訪問を喜ば詳細については、7月1日に2018を動作を停止します:残念ながら、このサービスは、このメッセージに従って7月1日2018を切断されますgithub.com/apilayer/freegeoip#readmeを \
フリオ・バイロン

20

https://geolocation-db.comのサービスを使用した純粋なJavascriptの例は、JSONおよびJSONPコールバックソリューションを提供します。

jQueryは必要ありません。

<!DOCTYPE html>
<html>
<head>
<title>Geo City Locator by geolocation-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://geoilocation-db.com/json/geoip.php?jsonp=callback';
    var h = document.getElementsByTagName('script')[0];
    h.parentNode.insertBefore(script, h);

</script> 
</html>

https://geoilocation-db.comAPIの使用に関する制限はありますか?
Priyanka Sharma

16

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>

9
The geolocation functionality in the Loader hasn't been retired, per se. We stopped documenting it several years ago and have recommended the HTML-based solutions due to their improved accuracy, but the functionality itself has not been removed from the Loader at this time. code.google.com/p/google-ajax-apis/issues/detail?id=586
TheFrost

このGoogle APIS IPジオロケーションの品質はどうですか?(それは、または私は間違っていますか?)、ipinfo.ioなどの他のサービスと比較して?
Basj

私はさまざまな都市で最大30人に依頼しましたが、Google APISのIPジオロケーションの品質はipinfo.ioと比較して劣っています
Basj

1
@Basj Google APIは魅力的ですが、ipinfo.ioは私が実際に中央ヨーロッパにいる間に米国にいることを示しています
patryk

15

http://www.hostip.info/などの外部サービスを使用する必要があります。「geo-ip」をグーグル検索すると、より多くの結果を得ることができます。

Host-IP APIはHTTPベースであるため、ニーズに応じてPHPまたはJavaScriptで使用できます。


6
私は1年間hostip.infoを使用していますが、感心していません。これは通常、未知の9/10のチェックを返す
アロン

同意して、私はウォーキングに住んでいると言っています...公平に言うと、GBのビットは正しくなりました...しかし、私はロンドンにいます。
Jamie Hutber、2013年

2
どのようなサービスも、利用可能な公開情報/データと同じくらい優れたものになることに留意してください。プライバシー上の理由により、この情報は「とても良い」ものにすぎません。それがあなたの国を正しくし、少なくとも州/地方に近い場合、私は勝利だと思います。これを使用してDOS攻撃の情報を検索している場合は、IPが有効でないこともあります(だれにも割り当てられていないか、有効なパブリックIP範囲外にある)。
eselk 2014

彼らのウェブサイトで「場所:...実際には手掛かりはありません。」と表示されます。私が知る必要があるすべて
Bojan Kogoj

15

私はipapi.coの APIを使用してボットを作成しました。IPアドレス(例1.2.3.4)の場所を取得する方法はphp次のとおりです。

ヘッダーを設定:

$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);

1
@Eoin削除しました。phpfiddleのIPが制限されているようです。
Jaimes 2017

10

この質問は保護されています。しかし、私はここで答えを見ません。私が見るのは、彼らが同じ質問を持つことから思いついたものを示している多くの人々です。

現在、IPの所有権に関する最初の連絡窓口として機能する、さまざまな程度の機能を持つ5つの地域インターネットレジストリがあります。プロセスは流動的です。そのため、ここでさまざまなサービスが機能し、機能しない場合があります。

だれが(明らかに)古代のTCPプロトコルであるか-それが最初に機能した方法は、ポート43への接続によるものでした。そのため、リース接続やファイアウォールを介したルーティングなどに問題が生じます。

現時点では、ほとんどのWho IsはRESTful HTTPおよびARINを介して行われ、RIPEおよびAPNICにはRESTfulサービスが機能しています。LACNICは503を返し、AfriNICにはそのようなAPIがないようです。(ただし、すべてオンラインサービスがあります。)

これにより、IPの登録済み所有者のアドレスが取得されますが、クライアントの場所は取得されません。クライアントから取得する必要があります。また、IPアドレスを要求する必要があります。また、プロキシは、発信者であると思われるIPを検証するときの心配が最も少ないものです。

人々は彼らが追跡されているという概念を理解していないので、私の考えでは、クライアントから直接そして彼らの許可を得てそれを取得し、その概念に多くのことを期待します。


8

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のようです。


1
unf。他のサービスと比較してHostIPはオフになっています.. www.ip-adress.comしかし、それを釘付けに
Scott Evernden

8

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

4
ipinfo.ioがデフォルトで発信者のIPの詳細を返すのは正しいことです。PHP Webサイトを実行している場合は、ユーザーのIPではなく、サーバーのIPになります。これが$ _SERVER ['REMOTE_ADDR']を渡す必要がある理由です。座標だけが必要な場合は、/ locをURLに追加して、そのフィールドだけを取得する方が簡単です。
ベンダウリング2014年

ああ、そうだね!/ locについては知りませんでした。自分のサイトですぐに修正します。
Isaac Askew 2014年

7

他のプロバイダーに依存せずに自分で実行したい場合、IP2Nationは、地域レジストリが状況を変えると更新されるマッピングのMySQLデータベースを提供します。


私は外部サービスを使用していて、突然私のウェブサイトがとても遅くなりました。外部サービスが情報を返信するのに20秒もかかりました。これは、訪問者にとって明らかに危険です。自分でやることにしたので、これは完璧な解決策です。ありがとうございます。
Williamz902 2018年

7

私はIPLocate.ioでサービスを実行します。これは、1回の簡単な呼び出しで無料でフックできます。

<?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オブジェクトは次のようにあなたのジオロケーションフィールドが含まれますcountrycityなど、

詳細については、ドキュメントをご覧ください。


7

Maxmindの無料のGeoLite Cityが気に入っています。これはほとんどのアプリケーションで機能し、十分に正確でない場合は有料バージョンにアップグレードできます。あるPHP APIは、他の言語用として、含まれています。また、Lighttpdをウェブサーバーとして実行している場合は、モジュールを使用することもできますを必要な場合はすべての訪問者のSERVER変数の情報を取得ます。

また、無料のGeolite Country(IPのある都市を特定する必要がない場合はより高速です)とGeolite ASN(IPの所有者を知りたい場合)もあり、最後にこれらすべてが独自のサーバーにダウンロード可能で、毎月更新され、提供されているAPIで「毎秒数千回の検索」が示されているため、すばやく検索できます。


1
あなたは無料のIP2Location LITE lite.ip2location.comを検討することができます。それは非常に便利な郵便番号情報まで持っています。
マイケルC.

6

PHPにはそのための拡張機能があります。

PHP.netから:

GeoIP拡張機能により、IPアドレスの場所を見つけることができます。市、州、国、経度、緯度、およびISPや接続タイプなどのその他すべての情報は、GeoIPを使用して取得できます。

例えば:

$record = geoip_record_by_name($ip);
echo $record['city'];

3
これは、PaywareであるMaxMindデータベースのphpモジュールです。(無料の「ライト」バージョンは非常に不正確です。)悪いことではありませんが、商業目的でのみ役立ちます。
誰かが

6

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>

免責事項;

サービスを構築しました。

複数の言語の例については、ドキュメントを参照してください

参照してくださいこれを最高のIPジオロケーションAPIを詳細に分析します。


5

誰かがこのスレッドに遭遇した場合のために、ここに別の解決策があります。でtimezoneapi.io、IPアドレスを要求して、代わりにいくつかのオブジェクトを取得できます(サービスを作成しました)。ユーザーがどのタイムゾーンにいるのか、世界のどこにいるのか、現在は何時なのかを知る必要があったために作成されました。

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);

    }

});

4

以下は、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" }

4

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
}

3

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();

2

「smart-ip」サービスを使用することもできます。

$.getJSON("http://smart-ip.net/geoip-json?callback=?",
    function (data) {
        alert(data.countryName);
        alert(data.city);
    }
);

2

IPアドレスサービスを使用して一連のテストを行ったので、自分で行う方法をいくつか紹介します。まず、私が使用する便利なWebサイトへのリンクをまとめます。

https://db-ip.com/db 無料のip-lookupサービスがあり、ダウンロードできるいくつかの無料のcsvファイルがあります。これは、メールに添付されている無料のapiキーを使用します。1日あたり2000クエリに制限されています。

http://ipinfo.io/ api-key PHP関数なしの無料のip-lookupサービス:

//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-addressを数値に変換します。たとえば、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

2

IPジオロケーションを実行するには、2つの広範なアプローチがあります。1つは、データセットをダウンロードし、インフラストラクチャでホストし、それを最新の状態に維持することです。特に多数のリクエストをサポートする必要がある場合、これには時間と労力が必要です。別のソリューションは、すべての作業を管理する既存のAPIサービスを使用することです。

Maxmind、Ip2location、Ipstack、IpInfoなど、多くのAPIジオロケーションサービスが存在します。最近、私が働いている会社はIpregistryhttps://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を宣伝するためにここにいるわけではなく、それが最良であると言いますが、私は既存のソリューションの分析に長い時間を費やしましたが、それらのソリューションは本当に有望です。


-1

更新された/正確なデータベースを検索している場合は、ここを使用することをお勧めします。これは、テスト中に他の多くのサービスに含まれていない正確な場所を示していたためです。
(私の街はRasht、私の国はIranこのIPアドレス2.187.21.235でした:私がテストしていたとき。)

ローカルでの処理がはるかに高速になるため、APIメソッドではなくデータベースを使用することをお勧めします。


-1

わかりました、皆さん、ご提案ありがとうございます。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"

自由に使って、修正して、もっと上手にやりましょう)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.