PHP

Скрипт распознавания города по ip адресу

10/15/2010, автор admin, категории Web-разработка
Очень давно не писали ничего, вроде накопилось у нас несколько интересных тем. Сегодня расскажу о сервисе позволяющем определять название города по ip пользователя зашедшего к вам. Сервис предоставляют http://ipgeobase.ru и помоему они отлично справляются.
Писать самому функции для работы с сервисом очень не хотелось поэтому откопал где то этот код:
<?php
/*
 This program is free software. You can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License.

 Home:   http://www.it2k.ru/projects/class-ipgeo/
 Author: Egor N. Zuskin

 Simple for php:
 $ipList = new IPGeo("xxx.xxx.xxx.xxx,xxx.xxx.xxx.xxx");
 print $ipList->ip("xxx.xxx.xxx.xxx"); // city: xxxx
 or
 $ipList = new IPGeo(array("xxx.xxx.xxx.xxx", "xxx.xxx.xxx.xxx"));
 print $ipList->ip("xxx.xxx.xxx.xxx","region"); // region: xxxx
 or
 $ipList = new IPGeo("xxx.xxx.xxx.xxx");
 print $ipList->ip("xxx.xxx.xxx.xxx", "district"); // district: xxxx
*/

DEFINE("IPGEO_SERVER", "194.85.91.253"); // сервер ip geo
DEFINE("IPGEO_SERVER_PORT", 8090);       // порт
DEFINE("IPGEO_DEFAULT_PARAM", "city");   // поле возвращаемое поумолчанию
DEFINE("IPGEO_DEBUG", false);            // признак отладки (не обращается к серверу)

/**
 * @author ice
 * Класс для получения ip адресов с сервиса ipgeobase.ru
 */
class IPGeo {

	var $xml        = "";           // текст возвращаемого xml
	var $ip_arr     = array();      // массив ip адресов
	var $fields_arr = array("all"); // список запрашиваемых полей
//	var $fields_arr = array("city");
	var $cache      = array();      // кешь ответа

	/**
	 * Создание класса и запрос к серверу
	 * @param $AIpList список ip адресов, строкой либо строкой через запятую либо массивом
	 * @return bool
	 */
	function IPGeo($AIpList)
	{

		if (IPGEO_DEBUG)
		{
			return true;
		}

		if (is_array($AIpList))
		{
			$ip_arr = $AIpList;
		}
		else
		{
			if (strpos($AIpList, ",") === False)
			{
				$ip_arr = array(trim($AIpList));
			}
			else
			{
				$ip_arr = explode(",",trim($AIpList));
			}
		}

		$ip_arr = array_unique($ip_arr);
		$ip_arr = $this->check_ip_list_valid($ip_arr);

		if (count($ip_arr) == 0)
			return false;

		$ips = "<ip>" . implode("</ip><ip>",$ip_arr) . "</ip>";
		$fields = "<" . implode("/><", $this->fields_arr)."/>";
		$post_string = "<ipquery><fields>".$fields."</fields><ip-list>".$ips."</ip-list></ipquery>";

		if (!$socket  = fsockopen(IPGEO_SERVER, IPGEO_SERVER_PORT))
			return false;

		$query  = "POST /geo/geo.html HTTP/1.1\r\n";
		$query .= "Content-Length: ".strlen ($post_string)."\r\n";
		$query .= "\r\n";
		$query .= $post_string;
		$query .= "\r\n\r\n";

		$response = "";
		fwrite($socket, $query);
		while (!feof($socket))
		{
			$response .= fgets($socket, 2048);
		}
		fclose($socket);
		$this->xml = trim(substr($response, strpos($response,"\r\n\r\n")));

		return true;
	}

	/**
	 * Возвращает запрошенное поле для ip адреса
	 * @param $AIp        IP адрес
	 * @param $AFiledName Поле
	 * @return string
	 */
	function ip($AIp, $AFiledName = IPGEO_DEFAULT_PARAM)
	{
        if (IPGEO_DEBUG)
        {
            return "not found";
        }

		if (isset($this->cache[$AIp][$AFiledName]))
		{
			return $this->cache[$AIp][$AFiledName];
		}
		else
		{
			if ($this->xml)
			{
				$doc = new DOMDocument;
				$doc->loadXML($this->xml);
				$xmlpath = new domxpath($doc);
				$ip_ansver = $doc->getElementsByTagName("ip-answer")->item(0);
				$items     = $xmlpath->query("ip", $ip_ansver);
				foreach ($items as $it)
				{
					$ip = $it->getAttribute('value');
					if ($ip == $AIp)
					{
						$message = @$xmlpath->query("message", $it)->item(0)->nodeValue;
						$field_value = ($message<>"") ? strtolower($message) : $xmlpath->query($AFiledName, $it)->item(0)->nodeValue;
						$this->cache[$AIp][$AFiledName] = $field_value;
						return $field_value;
					}
				}
			}
        }
        return "not found";
	}

	/**
	 * Возвращает список правельных ip адресов проверенных по маске xxx.xxx.xxx.xxx < 256
	 * @param $AIpList масив ip адресов
	 * @return array
	 */
	function check_ip_list_valid($AIpList)
	{
		$return = array();

		foreach($AIpList as $ip)
		{
			if (ereg("([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3}).([0-9]{1,3})",$ip, $par))
			{
				if ($par[1] < 256 && $par[2] < 256 && $par[3] < 256 && $par[4] < 256)
				{
					$return[] = $ip;
				}
			}
		}

		return $return;
	}

}

?>

подключается он очень просто
if(empty($_COOKIE['city']) || $_COOKIE['city']=="undefined") {
$IP= ($_SERVER['REMOTE_ADDR']);
if(!empty($IP)) {
  $ipList = new IPGeo($IP); //подключаем класс IPGeo
  $city= $ipList->ip($IP); // определяем город по ip
  $_COOKIE['city']=$city;
} else {
$city=$_COOKIE['city'];
}

Если город еще не был определен то определяем и записываем его в куки, иначе просто смотрим какое название города уже лежит в куках. Вобщем определение города по ip пишется не более чем пять минут, остальное уже дело техники.
Можно создать базу нужных городов на сайте и сверяться с ними по названию, и например показывать товары только по городу который выбрал пользователь. Для этого и используется в большинстве случаев определение города по ip
Теги:
ip
Добавлено: 22 Сентября 2013 01:39:29 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...