dirname = dirname(__file__); // ip if(!isset($options['ip']) OR !$this->is_valid_ip($options['ip'])) $this->ip = $this->get_ip(); elseif($this->is_valid_ip($options['ip'])) $this->ip = $options['ip']; // кодировка if(isset($options['charset']) && $options['charset'] && $options['charset']!='windows-1251') $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 - дополнительно читайте комментарии внутри функции. */ function get_value($key = false, $cookie = true) { $key_array = array('inetnum', 'country', 'city', 'region', 'district', 'lat', 'lng'); if(!in_array($key, $key_array)) $key = false; // если используем куки и параметр уже получен, то достаем и возвращаем данные из куки if($cookie && isset($_COOKIE['geobase'])) { $data = unserialize($_COOKIE['geobase']); } else { $data = $this->get_geobase_data(); setcookie('geobase', serialize($data), time()+3600*24*7); //устанавливаем куки на неделю } if($key) return $data[$key]; // если указан ключ, возвращаем строку с нужными данными else return $data; // иначе возвращаем массив со всеми данными } /** * функция получает данные по ip. * @return array - возвращает массив с данными */ function get_geobase_data() { // получаем данные по ip $link = 'ipgeobase.ru:7020/geo?ip='.$this->ip; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $link); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 3); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3); $string = curl_exec($ch); // если указана кодировка отличная от windows-1251, изменяем кодировку if($this->charset) $string = iconv('windows-1251', $this->charset, $string); $data = $this->parse_string($string); return $data; } /** * функция парсит полученные в XML данные в случае, если на сервере не установлено расширение Simplexml * @return array - возвращает массив с данными */ function parse_string($string) { $pa['inetnum'] = '#(.*)#is'; $pa['country'] = '#(.*)#is'; $pa['city'] = '#(.*)#is'; $pa['region'] = '#(.*)#is'; $pa['district'] = '#(.*)#is'; $pa['lat'] = '#(.*)#is'; $pa['lng'] = '#(.*)#is'; $data = array(); foreach($pa as $key => $pattern) { preg_match($pattern, $string, $out); if(isset($out[1]) && $out[1]) $data[$key] = trim($out[1]); } return $data; } /** * функция определяет ip адрес по глобальному массиву $_SERVER * ip адреса проверяются начиная с приоритетного, для определения возможного использования прокси * @return ip-адрес */ function get_ip() { $ip = false; if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) $ipa[] = trim(strtok($_SERVER['HTTP_X_FORWARDED_FOR'], ',')); if (isset($_SERVER['HTTP_CLIENT_IP'])) $ipa[] = $_SERVER['HTTP_CLIENT_IP']; if (isset($_SERVER['REMOTE_ADDR'])) $ipa[] = $_SERVER['REMOTE_ADDR']; if (isset($_SERVER['HTTP_X_REAL_IP'])) $ipa[] = $_SERVER['HTTP_X_REAL_IP']; // проверяем ip-адреса на валидность начиная с приоритетного. foreach($ipa as $ips) { // если ip валидный обрываем цикл, назначаем ip адрес и возвращаем его if($this->is_valid_ip($ips)) { $ip = $ips; break; } } return $ip; } /** * функция для проверки валидности ip адреса * @param ip адрес в формате 1.2.3.4 * @return bolean : true - если ip валидный, иначе false */ function is_valid_ip($ip=null) { if(preg_match("#^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$#", $ip)) return true; // если ip-адрес попадает под регулярное выражение, возвращаем true return false; // иначе возвращаем false } }