Ищу Ищу скрипт определения города и перенаправления на поддомен

Этот код в самом верху страницы.
Код:
<?php
function GetRealIp() {
 if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
   $ip=$_SERVER['HTTP_CLIENT_IP'];
 } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
  $ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
 } else {
   $ip=$_SERVER['REMOTE_ADDR'];
 }
 return $ip;
}
$realUserIP = GetRealIp();
?>

Этот после body
Код:
<script>

var ip = "<?php echo $realUserIP; ?>";
  jQuery.ajax ({
    type: "GET",
    url: "http://ipgeobase.ru:7020/geo/?ip=" + ip,
    dataType: "xml",
    success: function(xml) {
      var region = jQuery(xml).find('city').text();
      jQuery(".geocity").text(region);
    },
    error: function() {
      jQuery(".geocity").text("не определен");
    }
  });

</script>

Ну а дальше, уже отталкиваясь какие нужны города, на какие поддомены будут редиректиться допиливаем под себя.
Список айпишников и городов можно посмотреть на сайте [HIDEL="1"]http://ipgeobase.ru [/HIDEL]
 

В каком виде нужен скрипт? На PHP, например?
Куда предполагается его вставлять?

на вордпресс, ага на php лучше всего)

Этот код в самом верху страницы.
Код:
<?php
function GetRealIp() {
 if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
   $ip=$_SERVER['HTTP_CLIENT_IP'];
 } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
  $ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
 } else {
   $ip=$_SERVER['REMOTE_ADDR'];
 }
 return $ip;
}
$realUserIP = GetRealIp();
?>

Этот после body
Код:
<script>

var ip = "<?php echo $realUserIP; ?>";
  jQuery.ajax ({
    type: "GET",
    url: "http://ipgeobase.ru:7020/geo/?ip=" + ip,
    dataType: "xml",
    success: function(xml) {
      var region = jQuery(xml).find('city').text();
      jQuery(".geocity").text(region);
    },
    error: function() {
      jQuery(".geocity").text("не определен");
    }
  });

</script>

Ну а дальше, уже отталкиваясь какие нужны города, на какие поддомены будут редиректиться допиливаем под себя.
Список айпишников и городов можно посмотреть на сайте ***Скрытый текст***


спасибо, попробую разобраться
 

Ну а дальше, уже отталкиваясь какие нужны города, на какие поддомены будут редиректиться допиливаем под себя.
Если не трудно, можете привести пример с двумя поддоменами
msk.site.ru
spb.site.ru
 

Если не трудно, можете привести пример с двумя поддоменами
msk.site.ru
spb.site.ru
Можно вот так сделать, на одном php проще будет, сразу не подумал просто.
Создаем на хостинге файл geo.php от таким содержимым:
Код:
<?php
    class Geo
    {
        public function __construct($options = null) {
            
            $this->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 = false)
        {
            $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'] = '#<inetnum>(.*)</inetnum>#is';
            $pa['country'] = '#<country>(.*)</country>#is';
            $pa['city'] = '#<city>(.*)</city>#is';
            $pa['region'] = '#<region>(.*)</region>#is';
            $pa['district'] = '#<district>(.*)</district>#is';
            $pa['lat'] = '#<lat>(.*)</lat>#is';
            $pa['lng'] = '#<lng>(.*)</lng>#is';
            $data = array();
            foreach($pa as $key => $pattern)
            {
                if(preg_match($pattern, $string, $out))
                {
                    $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
        }
        

    }
?>

Ну и в файле(как пример) index.php прописываем:

Код:
<?php
    include('geo.php'); /*Подключаем файлик для определеления ГЕО*/
    global $sa; /*Задаём глобальную переменную, чтобы потом использовать в любом месте кода страницы*/
    $o = array();
    $o['charset'] = 'utf-8';
    $geo = new Geo($o);
    $country = $geo->get_value('country');  /*Выдираем страну из ГЕО базы*/
    $city = $geo->get_value('city');  /*Выдираем город из ГЕО базы*/
    if ( $city == 'Санкт-Петербург' ){            // url для отправки пользователей из Питера
        $url = "http://spb.site.ru";
        }
    if ( $city == 'Москва' ){            // url для отправки пользователей из Москвы
        $url = "http://msk.site.ru";
        }
        header("Location: $url"); // редирект по ссылке, в зависимости от города
    ?>

Но если вы собираетесь этак по 1600+ городам такое делать, то лучше прикрутить все это дело к MySQL.
И в идеале все таки желательно сначала давать юзеру попасть на основной домен, а уже потом спрашивать у него города, потому как в базах далеко не все айпишники, очень часто город определяется не правильно.
 

Можно вот так сделать, на одном php проще будет, сразу не подумал просто.
Создаем на хостинге файл geo.php от таким содержимым:
Код:
<?php
    class Geo
    {
        public function __construct($options = null) {
           
            $this->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 = false)
        {
            $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'] = '#<inetnum>(.*)</inetnum>#is';
            $pa['country'] = '#<country>(.*)</country>#is';
            $pa['city'] = '#<city>(.*)</city>#is';
            $pa['region'] = '#<region>(.*)</region>#is';
            $pa['district'] = '#<district>(.*)</district>#is';
            $pa['lat'] = '#<lat>(.*)</lat>#is';
            $pa['lng'] = '#<lng>(.*)</lng>#is';
            $data = array();
            foreach($pa as $key => $pattern)
            {
                if(preg_match($pattern, $string, $out))
                {
                    $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
        }
       

    }
?>

Ну и в файле(как пример) index.php прописываем:

Код:
<?php
    include('geo.php'); /*Подключаем файлик для определеления ГЕО*/
    global $sa; /*Задаём глобальную переменную, чтобы потом использовать в любом месте кода страницы*/
    $o = array();
    $o['charset'] = 'utf-8';
    $geo = new Geo($o);
    $country = $geo->get_value('country');  /*Выдираем страну из ГЕО базы*/
    $city = $geo->get_value('city');  /*Выдираем город из ГЕО базы*/
    if ( $city == 'Санкт-Петербург' ){            // url для отправки пользователей из Питера
        $url = "http://spb.site.ru";
        }
    if ( $city == 'Москва' ){            // url для отправки пользователей из Москвы
        $url = "http://msk.site.ru";
        }
        header("Location: $url"); // редирект по ссылке, в зависимости от города
    ?>

Но если вы собираетесь этак по 1600+ городам такое делать, то лучше прикрутить все это дело к MySQL.
И в идеале все таки желательно сначала давать юзеру попасть на основной домен, а уже потом спрашивать у него города, потому как в базах далеко не все айпишники, очень часто город определяется не правильно.


такое решение подойдет, если сайты на разных доменах. У меня wp multisite и поддмоены виртуальные, как в таком случае быть? у меня получается зацикленная переадрессация
 

такое решение подойдет, если сайты на разных доменах. У меня wp multisite и поддмоены виртуальные, как в таком случае быть? у меня получается зацикленная переадрессация
Ну как минимум повесить куки. Пришел в первый раз, повесили куки и отправили на поддомен(разницы то нет, виртуальный он или нет), далее он конечно же попадает фактически на тот же самый скрипт, который проверяет есть ли куки, если есть то запускать выполнение другого скрипта. А еще лучше делать редирект на js, проверяем на куки, если нет, то выводим редирект, если есть, то не выводим его.
 

Ну как минимум повесить куки. Пришел в первый раз, повесили куки и отправили на поддомен(разницы то нет, виртуальный он или нет), далее он конечно же попадает фактически на тот же самый скрипт, который проверяет есть ли куки, если есть то запускать выполнение другого скрипта. А еще лучше делать редирект на js, проверяем на куки, если нет, то выводим редирект, если есть, то не выводим его.

дописал так:

setcookie("gorod", $city);
$gor = $_COOKIE["gorod"];
if (!isset($gor) and $gor = "Свердловская область"){header("Location: https://ekb.site.ru");}

но не работает, если убрать !isset($gor) то идет зацикливание. что не так?(
 

дописал так:

setcookie("gorod", $city);
$gor = $_COOKIE["gorod"];
if (!isset($gor) and $gor = "Свердловская область"){header("Location: https://ekb.site.ru");}

но не работает, если убрать !isset($gor) то идет зацикливание. что не так?(
Код:
<?php
    include('geo.php');
    global $sa;
    $o = array();
    $o['charset'] = 'utf-8';
    $geo = new Geo($o);
    $country = $geo->get_value('country');
    $city = $geo->get_value('city');
    $gor = $_COOKIE["gorod"];
if ( $gor == $city ){
        $url = "http://ya.ru";
        }
    else {  setcookie("gorod", $city);
 $url = "http://vk.cc";
}
header("Location: $url");
   ?>

Если кука есть то отправляем на ya.ru, если куки нет, то ставим ее и отправляем на vk.cc, при повторном заходе мы попадем на ya.ru.

Еще можно сделать по другому. Все пользователи сначала попадают на site.ru, далее редиректятся, Москва на msk.site.ru, но в коде мы ставим проверку на домен, если скрипт говорит что мы сейчас на site.ru, то редиректим, если на msk.site.ru то ничего не делаем.
 

Код:
<?php
    include('geo.php');
    global $sa;
    $o = array();
    $o['charset'] = 'utf-8';
    $geo = new Geo($o);
    $country = $geo->get_value('country');
    $city = $geo->get_value('city');
    $gor = $_COOKIE["gorod"];
if ( $gor == $city ){
        $url = "http://ya.ru";
        }
    else {  setcookie("gorod", $city);
 $url = "http://vk.cc";
}
header("Location: $url");
   ?>

Если кука есть то отправляем на ya.ru, если куки нет, то ставим ее и отправляем на vk.cc, при повторном заходе мы попадем на ya.ru.

Еще можно сделать по другому. Все пользователи сначала попадают на site.ru, далее редиректятся, Москва на msk.site.ru, но в коде мы ставим проверку на домен, если скрипт говорит что мы сейчас на site.ru, то редиректим, если на msk.site.ru то ничего не делаем.

не работает такой код, всеравно циклическая переадресация получается =(

Сайт ekb.site.ru выполнил переадресацию слишком много раз.
 

не работает такой код, всеравно циклическая переадресация получается =(

Сайт ekb.site.ru выполнил переадресацию слишком много раз.
Ну я хз тогда...
Взял домен as-blog.ru, создал поддомен msk.as-blog.ru, что домен, что поддомен привязаны к одной и той же папке. Закинул туда файл index.php со следующим кодом
Код:
<?php
    $gor = $_COOKIE["gorod"];
if ( $gor == "msk" ){
        echo "Все ЗБС";
        }
    else {  setcookie("gorod", "msk");
 $url = "http://msk.as-blog.ru";
 header("Location: $url");
}

   ?>
Работоспособность можно проверить по ссылке as-blog.ru
 

Назад
Сверху