big-moving.ru/api/soft/geo.php

129 lines
5.9 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
class Geo {
var $ip;
var $charset = 'utf-8';
/**
* Создаем объект с заданными настройками.
* @param array $options
* @return void
*/
public function __construct(array $options = array()) {
// ip
if (isset($options['ip']) && $this->is_valid_ip($options['ip'])) {
$this->ip = $options['ip'];
} else {
$this->ip = $this->get_ip();
}
// кодировка
if (isset($options['charset']) && is_string($options['charset'])) {
$this->charset = $options['charset'];
}
}
/**
* функция возвращет конкретное значение из полученного массива данных по ip
* @param string - ключ массива. Если интересует конкретное значение.
* Ключ может быть равным 'inetnum', 'country', 'city', 'region', 'district', 'lat', 'lng'
* @param bolean - устанавливаем хранить данные в куки или нет
* Если true, то в куки будут записаны данные по ip и повторные запросы на ipgeobase происходить не будут.
* Если false, то данные постоянно будут запрашиваться с ipgeobase
* @return array OR string - дополнительно читайте комментарии внутри функции.
*/
public function get_value($key = null, $cookie = true) {
$key_array = array('inetnum', 'country', 'city', 'region', 'district', 'lat', 'lng');
if (!in_array($key, $key_array)) {
$key = null;
}
$data = $this->get_data($cookie);
if ($key) { // если указан ключ
if (isset($data[$key])) { // и значение есть в массиве данных
return $data[$key]; // возвращаем строку с нужными данными
} elseif ($cookie) { // иначе если были включены куки
return $this->get_value($key, false); // пытаемся вернуть данные без использования cookie
}
return NULL; // если ничего нет - отдаем NULL
}
return $data; // иначе возвращаем массив со всеми данными
}
/**
* Получаем данные с сервера или из cookie
* @param boolean $cookie
* @return string|array
*/
public function get_data($cookie = true) {
// если используем куки и параметр уже получен, то достаем и возвращаем данные из куки
if ($cookie && filter_input(INPUT_COOKIE, 'geobase')) {
return unserialize(filter_input(INPUT_COOKIE, 'geobase'));
}
$data = $this->get_geobase_data();
if (!empty($data)) {
setcookie('geobase', serialize($data), time() + 3600 * 24 * 7, '/'); //устанавливаем куки на неделю
}
return $data;
}
/**
* функция получает данные по ip.
* @return array - возвращает массив с данными
*/
protected function get_geobase_data() {
// получаем данные по ip
$ch = curl_init('http://ipgeobase.ru:7020/geo?ip=' . $this->ip);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 3);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
$string = curl_exec($ch);
// если указана кодировка отличная от windows-1251, изменяем кодировку
if ($this->charset != 'windows-1251' && function_exists('iconv')) {
$string = iconv('windows-1251', $this->charset, $string);
}
$data = $this->parse_string($string);
return $data;
}
/**
* функция парсит полученные в XML данные в случае, если на сервере не установлено расширение Simplexml
* @return array - возвращает массив с данными
*/
protected function parse_string($string) {
$params = array('inetnum', 'country', 'city', 'region', 'district', 'lat', 'lng');
$data = $out = array();
foreach ($params as $param) {
if (preg_match('#<' . $param . '>(.*)</' . $param . '>#is', $string, $out)) {
$data[$param] = trim($out[1]);
}
}
return $data;
}
/**
* функция определяет ip адрес по глобальному массиву $_SERVER
* ip адреса проверяются начиная с приоритетного, для определения возможного использования прокси
* @return ip-адрес
*/
public function get_ip() {
$keys = array('HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'REMOTE_ADDR', 'HTTP_X_REAL_IP');
foreach ($keys as $key) {
$ip = trim(strtok(filter_input(INPUT_SERVER, $key), ','));
if ($this->is_valid_ip($ip)) {
return filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
}
}
}
/**
* функция для проверки валидности ip адреса
* @param ip адрес в формате 1.2.3.4
* @return bolean : true - если ip валидный, иначе false
*/
public function is_valid_ip($ip) {
return (bool)filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
}
}