В целом простая задача, возникла у меня недавно для получения данных регистрирующегося пользователя выявить его страну, город и его часовой пояс.
Конечно можно решать разными способами, загрузить себе базу с кучей 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 ];
}
}
Комментарии (4)
RSS свернуть / развернутьdark_barker
MpaK
для Башкирии у меня есть своя база с диапазонами ай-пишников по нему и проверяет… благо диапазонов не так много
MFD
MpaK
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.