从IP地址获取位置
我想从他们的IP地址检索访客的城市,州和国家的信息,以便我可以根据他们的位置定制我的网页。 有没有一个好的可靠的方式来做到这一点在PHP中? 我使用JavaScript进行客户端脚本,PHP进行服务器端脚本编写,MySQL使用数据库。
您可以下载免费的GeoIP数据库并在本地查找IP地址,也可以使用第三方服务并执行远程查询。 这是更简单的选项,因为它不需要设置,但是确实会引入额外的延迟。
您可以使用的第三方服务是我的http://ipinfo.io 。 他们提供主机名,地理位置,networking所有者和其他信息,例如:
$ 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": "" }
您需要使用外部服务…如http://www.hostip.info/如果谷歌search“geo-ip”,你可以得到更多的结果。;
Host-IP API是基于HTTP的,所以你可以根据你的需要在PHP或JavaScript中使用它。
使用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>
我使用ipapi.co的API编写了一个bot,下面是如何在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);
我将在这里做出与PHP服务相同的答案:
我喜欢Maxmind免费的GeoLite City ,适用于大多数应用程序,如果不够精确,可以从中升级到付费版本。 有一个PHP API包括,以及其他语言。 如果您将Lighttpd作为Web服务器运行,那么甚至可以使用模块为每个访问者获取SERVERvariables中的信息(如果这是您需要的)。
我应该补充说,还有一个免费的Geolite国家 (如果你不需要查明IP是从哪里来的话,速度会更快),Geolite ASN(如果你想知道谁拥有IP),最后所有这些都是可以在您自己的服务器上下载,每个月都会更新一次,并且在提供的API每秒查看数千次查询时,都可以快速查找。
从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。
假设你想自己做,而不是依靠其他的提供者, IP2Nation提供了一个映射的MySQL数据库,这些数据库随着区域注册pipe理机构的变化而更新。
PHP有一个扩展。
从PHP.net:
GeoIP扩展允许您查找IP地址的位置。 城市,州,国家,经度,纬度和其他所有信息,如ISP和连接types可以在GeoIP的帮助下获得。
例如:
$record = geoip_record_by_name($ip); echo $record['city'];
Ben Dowling的回应服务已经改变了,所以现在更简单了。 要find位置,只需执行以下操作:
// 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
坐标返回单个string像'31,-80',所以从那里你只是:
$coordinates = explode(",", $details->loc); // -> '31,-89' becomes'31','-80' echo $coordinates[0]; // latitude echo $coordinates[1]; // longitude
一个纯Javascript的例子,使用https://geoip-db.com的服务它们提供了一个JSON和JSONPcallback的解决scheme。;
- JSON: https : //geoip-db.com/json
- JSONPcallback: https : //geoip-db.com/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>
这个问题是受保护的,我明白了。 但是,我在这里没有看到答案,我看到的是很多人展示他们提出了同样的问题。
目前有五个区域互联网注册pipe理机构具有不同程度的function,作为知识产权所有权的第一个联络点。 这个过程是不断变化的,这就是为什么这里的各种服务有时候工作,而不是在其他时间。
然而,谁是(显然)是一个古老的TCP协议 – 它最初的工作方式是通过连接到端口43,这使得它通过租用连接,通过防火墙等路由问题。
在这一刻 – 大多数谁是通过RESTful HTTP和ARIN完成的,RIPE和APNIC都有RESTful服务。 LACNIC的回报503和AfriNIC显然没有这样的API。 (但是都有在线服务。)
这会让你知道知识产权的注册所有者的地址,但不是你的客户的位置,你必须从他们那里得到这个信息,而且你必须要求。 另外,在validation您认为是创build者的IP时,代理是您最担心的问题。
人们不理解他们正在被追踪的观念,所以 – 我的想法是 – 从客户那里直接获得并得到他们的许可,并且期望很多人会忽视这个概念。
以下是我发现使用http://ipinfodb.com/ip_locator.php获取其信息的代码片段的修改版本。; 请记住,您也可以使用API密钥申请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" }
如果有人绊倒这个线程,这是另一个解决scheme。 在timezoneapi.io你可以请求一个IP地址,并得到几个对象作为回报(我已经创build了服务)。 它的创build是因为我需要知道我的用户在哪个时区,世界上的哪个地方以及目前的时间。
在PHP中 – 返回位置,时区和date/时间:
// 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); } });
我为ipinfo.io创build了一个包装器 。 你可以使用composer php来安装它。
你可以这样使用它:
$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();
你也可以使用“smart-ip”服务:
$.getJSON("http://smart-ip.net/geoip-json?callback=?", function (data) { alert(data.countryName); alert(data.city); } );
我已经做了一堆IP地址服务testing,这里有一些我自己做的方法。 首先closures我使用的有用网站链接:
https://db-ip.com/db有一个免费的ip查找服务,并有几个免费的csv文件,你可以下载。; 这使用一个免费的API密钥,附加到您的电子邮件。 它限制在每天2000个查询。
http://ipinfo.io/没有api-key的免费ip-lookup服务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提供一堆可下载的文件,并附带说明将它们导入数据库。; 一旦你在数据库中有一个这样的文件,你可以很容易地select数据。
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
如果您需要从IP地址获取位置信息,则可以使用可靠的地理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 }
我几个月前写了这篇文章,可能对你有帮助。 本文介绍了ip2国家的开放源码数据库的使用情况,还介绍了为了使开放源代码数据库正常工作而编写的一个php类。 链接在这里
http://www.samundra.com.np/find-visitors-country-using-his-ip-address/1018
如果您需要任何帮助,请在我的网站留言。
希望它可以帮助你。
如果你正在寻找一个更新的/准确的数据库,我build议在这里使用这个数据库,因为它显示了我的确切位置,这个位置在我testing的时候没有被包含在许多其他服务中。
(我的城市是Rasht
,我的国家是Iran
,这个IP地址是2.187.21.235
当时我正在testing。)
我build议使用数据库而不是API方法,因为它将在本地处理得更快。
好的,伙计们,谢谢你的build议。 虽然我有6k +的IP,但由于某些限制,某些服务会使我的请求失败; 所以,你可以在后备模式下使用它们。
如果我们有以下格式的源文件:
user_id_1 ip_1 user_id_2 ip_2 user_id_3 ip_1
比你可以使用这个简单的expample命令(PoC)的Yii:
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"
随意使用,修改,并做得更好)
我运行https://ipdata.co它提供了几个数据点ip
在PHP中
php > $ip = '8.8.8.8'; php > $details = json_decode(file_get_contents("https://api.ipdata.co/{$ip}")); php > echo $details->region; California php > echo $details->city; Mountain View php > echo $details->country_name; United States php > echo $details->latitude; 37.751