Я хочу получить информацию, такую как город, штат и страну посетителя, с их IP-адреса, чтобы я мог настроить свою веб-страницу в соответствии с их местоположением. Есть ли хороший и надежный способ сделать это на 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": "" }
Вам нужно использовать внешнюю службу … например http://www.hostip.info/, если вы ищете Google для «geo-ip», вы можете получить больше результатов.
API-интерфейс Host-IP основан на 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>
Я написал бота, используя API от ipapi.co , вот как вы можете получить местоположение для 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);
Я сделаю тот же ответ, который я сделал здесь, поскольку служба также доступна для PHP:
Мне нравится бесплатный GeoLite City от Maxmind, который работает для большинства приложений и из которого вы можете перейти на платную версию, если она недостаточно точна. Существует API PHP , а также для других языков. И если вы используете Lighttpd в качестве веб-сервера, вы можете даже использовать модуль для получения информации в переменной SERVER для каждого посетителя, если это то, что вам нужно.
Я должен добавить, что есть также бесплатная Geolite Country (которая была бы быстрее, если бы вам не нужно было определить город из IP-адреса) и Geolite ASN (если вы хотите знать, кто владеет IP-адресом), и, наконец, все это загружаемые на ваш собственный сервер, обновляются каждый месяц и довольно быстро просматриваются с предоставленными API, поскольку они указывают «тысячи запросов в секунду».
Посмотрите на API из hostip.info – он предоставляет много информации.
Пример в 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 для сопоставлений, которые обновляются, поскольку региональные реестры меняют ситуацию.
PHP имеет расширение для этого.
От PHP.net:
Расширение GeoIP позволяет вам найти местоположение IP-адреса. Город, Страна, Страна, Долгота, Широта и другая информация, так как все, такие как ISP и тип соединения, могут быть получены с помощью GeoIP.
Например:
$record = geoip_record_by_name($ip); echo $record['city'];
Служба в ответ Бен Доулинг изменилась, так что теперь это проще. Чтобы найти местоположение, просто выполните:
// 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
Этот вопрос защищен, что я понимаю. Тем не менее, я не вижу здесь ответа, то, что я вижу, – это много людей, которые демонстрируют, что они придумали, имея тот же вопрос.
В настоящее время существует пять региональных интернет-реестров с разной степенью функциональности, которые служат первой точкой контакта в отношении права собственности на ИС. Процесс протекает, поэтому различные службы здесь работают иногда и не в разное время.
Кто есть (очевидно) древний протокол TCP, однако – то, как он работал первоначально, был подключен к порту 43, что затрудняет его маршрутизацию через арендованные соединения, через брандмауэры … и т. Д.
На данный момент – большинство Who Is сделано через RESTful HTTP и ARIN, RIPE и APNIC имеют службы RESTful, которые работают. LACNIC возвращает 503, а AfriNIC, по-видимому, не имеет такого API. (Однако у всех есть онлайн-услуги).
Это поможет вам – адрес зарегистрированного владельца IP, но – не местоположение вашего клиента – вы должны получить это от них, а также – вы должны попросить об этом. Кроме того, прокси-сервер является наименьшим из ваших проблем при проверке IP, который, по вашему мнению, является инициатором.
Люди не понимают, что их отслеживают, поэтому – мои мысли – получайте это от своего клиента напрямую и с их разрешения и ожидайте многого, чтобы отказаться от понятия.
Чистый пример 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>
Ниже приведена модифицированная версия фрагмента, который я нашел, который использует 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" }
Если кто-то наткнется на эту нить, вот еще одно решение. На 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); } });
Я создал оболочку для ipinfo.io . Вы можете установить его с помощью композитора.
Вы можете использовать его таким образом:
$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-адресов, и вот несколько способов сделать это самостоятельно. Прежде всего, удалите ссылки на полезные сайты, которые я использую:
https://db-ip.com/db Имеет бесплатный сервис ip-lookup и имеет несколько бесплатных файлов csv, которые вы можете загрузить. Это использует бесплатный ключ api, который прикреплен к вашей электронной почте. Он ограничивает 2000 запросов в день.
http://ipinfo.io/ Бесплатный сервис ip-lookup без функций PHP-api-key:
//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 * 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-адреса, вы можете использовать надежный сервис 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 }
Я запускаю службу на 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
и т. Д.
Ознакомьтесь с документами для получения дополнительной информации.
Я написал эту статью несколько месяцев назад и может быть полезен для вас. В статье описывается использование базы данных с открытым исходным кодом страны ip 2, а также описывается класс php, который я написал, чтобы работать с этой базой данных с открытым исходным кодом. Ссылка здесь
http://www.samundra.com.np/find-visitors-country-using-his-ip-address/1018
Если вам нужна помощь, пожалуйста, напишите мне на сайте.
Надеюсь, это поможет вам.
Если вы ищете обновленную / точную базу данных, я рекомендую использовать ее здесь, потому что она показывала мое точное местоположение, которое не было включено во многие другие службы, когда я тестировал.
(Мой город был Rasht
а моя страна была Iran
с этим ip-адресом: 2.187.21.235
когда я тестировал.)
Я рекомендую использовать базу данных, а не методы API, потому что она будет обрабатываться намного быстрее локально.
Хорошо, ребята, спасибо за ваши предложения; В то время как у меня есть 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