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

129 lines
5.9 KiB
PHP
Raw Normal View History

2022-06-24 15:29:23 +05:00
<?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);
}
}