Получени GEO данных по IP

В целом простая задача, возникла у меня недавно для получения данных регистрирующегося пользователя выявить его страну, город и его часовой пояс.

Конечно можно решать разными способами, загрузить себе базу с кучей ip данных и получать из неё, быстро и удобно, но проблема, что придётся заниматься поддержанием базы в актуальном состоянии. Я как человек ленивый, хотел бы упростить задачу и нашел веб-сервис, который отдаёт по запросу на ip адрес данные в 2х форматах, JSON и XML. Так как JSON мне как-то ближе и проще, то был набросан быстро класс старающийся как бы тише и спокойно отдать мне информацию по IP.

Класс и короткий пример прилагаю, юзайте на здоровье так сказать.
// пример получения данных по IP
$ip = new GeoIP( '217.69.128.44' );
if( $ip->error ){
	echo $ip->error_msg();
	exit();
}

echo  'IP: '.$ip->ip.': '.$ip->country.', '.$ip->city.'<br />';

/**
 * Класс GeoIP для получения данных по IP адресу
 */
class GeoIP{

    // наши публичные данные о запросе
	public
	$country		=	'',
	$country_code	=	'',
	$region_name	=	'',
	$city			=	'',
	$zip			=	'',
	$timezone		=	'',
	$gmt			=	'',
	$ip				=	'',
	$error			=	FALSE;



    // текста ошибок
	protected
	$error_msgs		=	array(
		1	=>	'Не удалось получить файл с сервера, проверьте директиву allow_url_fopen и/или подключен ли CURL',
		2	=>	'Не достаточная версия PHP, должно быть >= 5.2+',
	),
    // адрес откуда будем спрашивать
	$url    =	'http://www.ipinfodb.com/ip_query.php?output=json&ip='
	;

    /**
     * Создаем объект с нашей информацией по IP или флаг ошибки
     *
     * @param string $ip
     * @return object
     */
	public function __construct( $ip='' ){
        // если json_decode то критическая ошибка
		if( !function_exists('json_decode') ){
			$this->error = 2;
			return;
		}

		$url = $this->url.$ip;

        // попробуем получить данные из страницы через стандартные функции
		$json = $this->get_fopen( $url );
        // если не получилось, то попробуем через CURL
		if( $json === FALSE ) $json = $this->get_curl( $url );
        // если получилось, то разберем наш JSON и заполним данные
		if( $json !== FALSE ){
			$geo = json_decode( $json, TRUE );
			$this->country		= $geo['CountryName'];
			$this->country_code	= $geo['CountryCode'];
			$this->region_name	= $geo['RegionName'];
			$this->city			= $geo['City'];
			$this->zip			= $geo['ZipPostalCode'];
			$this->timezone		= $geo['Timezone'];
			$this->gmt			= $geo['Gmtoffset'];
			$this->ip			= $ip;

			$this->error		= FALSE;
		}

	}

    /**
     * Получаем страницу по url через стандартную функцию
     *
     * @param string $url
     * @return string
     */
	protected function get_fopen( $url ){
        // если запретили открывать url в php.ini то ошибка
  		if( !ini_get('allow_url_fopen') ) {
  			$this->error = 1;
	  		return FALSE;
		}
		return file_get_contents( $url );
	}

    /**
     * Получаем страницу по url с помощью CURL
     *
     * @param string $url
     * @return string
     */
	protected function get_curl( $url ){
        // если не подключен модуль CURL то ошибка
		if( !function_exists('curl_init') ){
  			$this->error = 1;
	  		return FALSE;
		}
        // инит, всякие флаги для неполучения заголовка, таймаута и возврата только контента
		$ch = curl_init();
		curl_setopt( $ch, CURLOPT_URL, $url );
		curl_setopt( $ch, CURLOPT_HEADER, 0 );
		curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 15 );
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		$text = curl_exec($ch);
		curl_close($ch);
		return $text;
	}

    // геттер так сказать для озвучки нашего номера ошибки в сообщение
	public function error_msg( $out='text' ){
		if( empty($this->error) ) return '';
		return $this->error_msgs[ $this->error ];
	}

}
  • +1
  • 19 декабря 2009, 13:51
  • MpaK

Комментарии (4)

RSS свернуть / развернуть
+
0
А как там с достоверностью? Ты сам првоерял? Большинство из них выдают хуйню, для уфанетовских — москву итд.
avatar

dark_barker

  • 19 декабря 2009, 13:57
+
0
Базу обещаются обновлять, потому будем надеяться на лучший разброс :)
avatar

MpaK

  • 19 декабря 2009, 14:01
+
0
кстати это очень рискованно зависеть от стороннего сервиса…
для Башкирии у меня есть своя база с диапазонами ай-пишников по нему и проверяет… благо диапазонов не так много
avatar

MFD

  • 7 февраля 2010, 04:51
+
0
;-) этот смайл тебе подмигивает по поводу базы ^_^
avatar

MpaK

  • 7 февраля 2010, 15:11

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.