2010-11-11 4 views
0

У меня есть веб-сайт, и я хочу, чтобы он идентифицировал местоположение пользователя и в соответствии с этим переместил пользователя в правильный субдомен. Пример: Если я иду на сайт из Франции, я хочу это перенаправить меня www.website.com/France и бросить на ...Нужна помощь с определением местонахождения на сайте

Как я могу это сделать, пожалуйста?

ответ

0

На уровне сервера приложений вы можете узнать, в какой стране пользователь, просматривая его в базе данных ip-2. Обычно это продукты, которые вы покупаете у компании-производителя программного обеспечения, специализирующейся на этом, с различными базами данных для разных нужд.

Вот один: ip2country

Вы также можете сделать это на ДНС-уровне, если у вас есть провайдера DNS, который может сделать это для вас. Вероятно, это имеет для вас смысл. Затем ваши посетители сразу будут отправлены на ближайший сервер без необходимости сначала связываться с сервером «диспетчера» (сервером DNS будет маршрутизатор), после чего правильный ip будет кэшироваться каким-то образом между сервером DNS, ответственным за домен и DNS-сервер на всем пути к пользователю.

+0

Я исправляю себя - кажется, вы хотите, чтобы все запросы отправлялись на один и тот же сервер, поэтому решение dns не то, что вы хотите, но я оставил его на данный момент, поскольку это все еще что-то, что вы, возможно, захотите рассмотреть. –

+0

Спасибо за ваш ответ, но я ищу быстрое и бесплатное решение, если у вас есть. – 2010-11-11 20:06:43

+0

Кажется, имеется бесплатная доступная база данных, которая не настолько точна, но должна быть достаточной. Я мог бы использовать это сам :) http://www.maxmind.com/app/geoip_country –

0

Вот решение, которое я использую на своем сайте [www.vladonai.com] [1], это 100% бесплатно (с использованием ежедневного обновления [www.zaigadgets.com/geoip][2] источника) , очень быстро (возможно, намного быстрее, чем MySQL мог бы сделать), а не требует базы данных. База данных хранится в двоичном файле, поэтому все, что вам нужно, - это любая версия PHP.

Функция для преобразования IP в имя Страна выглядит следующим образом:

function GetCountryFromIP($ip = "") 
{ 
    if ($ip == "") 
     $ip = $_SERVER['REMOTE_ADDR']; 

    //the db obtained from ZaiGadgets.com and converted using convert_ip2country_db_from_csv_to_binary_file_format function 
    $db_file_path = ip2Country_binary_db_filename; 
    if (!file_exists($db_file_path)) 
     return ""; 
    $db_file_handle = fopen($db_file_path, "rb"); 
    if (!$db_file_handle) 
     return ""; 

    $one_record_size = 10; //bytes 
    $low = 0; 
    $high = (filesize($db_file_path)/$one_record_size) - 1; 
    $mid = 0; 
    $ipFrom = 0; 
    $ipTo = 0; 

    $ipArrParts = explode('.', $ip); 
    $ipLong = ($ipArrParts[0] * 0x1000000) + ($ipArrParts[1] * 0x10000) + ($ipArrParts[2] * 0x100) + ($ipArrParts[3]); 

    $country = ""; //result 

    while($low <= $high) 
    { 
     $mid = (int)(($low + $high)/2); 
     $file_pos = $mid * $one_record_size; 
     fseek($db_file_handle, $file_pos, SEEK_SET); 

     $ipFrom = ipdbv2_read32($db_file_handle); 
     $ipTo = ipdbv2_read32($db_file_handle); 

     if ($ipFrom < 0) 
      $ipFrom += pow(2, 32); 
     if ($ipTo < 0) 
      $ipTo += pow(2, 32); 

     if (($ipLong >= $ipFrom) && ($ipLong < $ipTo)) 
     { 
      //found IP range :) 
      //echo "Found!!!!!<br>"; 
      $country = fread($db_file_handle, 2); 
      fclose($db_file_handle); 

      $country = GetCountryNameFromCountryCode($country); 

      return $country; 
     } else 
     { 
      if($ipLong <$ipFrom) 
      { 
       $high = $mid - 1; 
      } else 
      { 
       $low = $mid + 1; 
      } 
     } 
    } 

    fclose($db_file_handle); 

    return ""; 
} 

function ipdbv2_read32($db_file_handle) 
{ 
    $data = fread($db_file_handle, 4); 

    $output = unpack('V', $data); 
    $val_32_bit = $output[1]; 

    if ($val_32_bit < 0) 
     $val_32_bit += 4294967296; //correct signed/unsigned issue on 32-bit platforms 

    return $val_32_bit; 
} 

Перед использованием функции выше вам необходимо скомпилировать файл datbase с помощью функции ниже:

define("ip2Country_binary_db_filename", "ip2country_zaigadgets.bin"); 

function convert_ip2country_db_from_csv_to_binary_file_format($input_file_path = "") 
{ 
    //convert dataf from ZaiGadgets.com to binary db format 
    if ($input_file_path == "") 
     $input_file_path = "db.csv"; 
    $output_file_path = ip2Country_binary_db_filename; 

    $input_file_content = file_get_contents($input_file_path); //read_text_file_content($input_file_path); 

    if ($input_file_content == "") 
    { 
     echo "Error: empty input db - " . $input_file_path . "<br>"; 
     return; //nothing to do 
    } 

    unlink($output_file_path); //delete file content 
    $out_fileHandle = fopen($output_file_path, "cb"); 
    if (!$out_fileHandle) 
    { 
     echo "ERROR: Cannot Create file! " . $output_file_path . "<br>"; 
     return; 
    } 

    $records_count = 0; 
    $input_file_lines = explode("\n", $input_file_content); //split it to lines 
    echo "Text lines count: " . count($input_file_lines) . "<br>"; 

    //for ($input_line_n = 0; $input_line_n < 10; $input_line_n ++) 
    for ($input_line_n = 0; $input_line_n < count($input_file_lines); $input_line_n ++) 
    { 
     $sub_line = $input_file_lines[$input_line_n]; 
     if (strlen($sub_line) > 0 && is_numeric($sub_line[0])) 
     { 
      $sub_values = explode(",", $input_file_lines[$input_line_n]); 
      if (count($sub_values) == 4) 
      { 
       $start_ip_addr = $sub_values[0]; 
       $end_ip_addr = $sub_values[1]; 
       $country_code = $sub_values[2]; 
       if (strlen($country_code) == 2) 
       { 
        fwrite($out_fileHandle, pack("V", (float)$start_ip_addr), 4); 
        fwrite($out_fileHandle, pack("V", (float)$end_ip_addr), 4); 
        fwrite($out_fileHandle, $country_code, strlen($country_code)); 
        $records_count ++; 
       } else 
       { 
        echo "Invalid line " . $input_line_n . " [wrong country len]: " . $sub_line . "<br>"; 
       } 
      } else 
      { 
       echo "Invalid line " . $input_line_n . ": " . $sub_line . "<br>"; 
      } 
     } else 
     if ($sub_line != "" && $sub_line[0] != '#' && $sub_line != "startip,endip,countrycode,countryname") 
     { 
      echo "Invalid line " . $input_line_n . ": " . $sub_line . "<br>"; 
     } 
    } 
    fclose($out_fileHandle); 

    echo "Data size verification result: " . ($records_count * 10 == filesize($output_file_path) ? "OK" : "Error") . "<br>"; 
    echo "Exported records (blocks) count: " . $records_count . "<br>"; 
    echo "Exporting complete.<br>"; 
} 

Теперь, если вам это нравится, вы можете использовать функцию ниже для преобразования двухбуквенного кода страны в название страны:

function GetCountryNameFromCountryCode($country_code, $b_very_strict = false) 
{ 
    $countries = array (
     "ac" => "ASCENSION ISLAND", 
     "ad" => "ANDORRA", 
     "ae" => "UNITED ARAB EMIRATES", 
     "af" => "AFGHANISTAN", 
     "ag" => "ANTIGUA AND BARBUDA", 
     "ai" => "ANGUILLA", 
     "al" => "ALBANIA", 
     "am" => "ARMENIA", 
     "an" => "NETHERLANDS ANTILLES", 
     "ao" => "ANGOLA", 
     "aq" => "ANTARCTICA", 
     "ar" => "ARGENTINA", 
     "as" => "AMERICAN SAMOA", 
     "at" => "AUSTRIA", 
     "au" => "AUSTRALIA", 
     "aw" => "ARUBA", 
     "ax" => "ALAND", 
     "az" => "AZERBAIJAN", 
     "ba" => "BOSNIA AND HERZEGOVINA", 
     "bb" => "BARBADOS", 
     "bd" => "BANGLADESH", 
     "be" => "BELGIUM", 
     "bf" => "BURKINA FASO", 
     "bg" => "BULGARIA", 
     "bh" => "BAHRAIN", 
     "bi" => "BURUNDI", 
     "bj" => "BENIN", 
     "bl" => "SAINT BARTHELEMY", 
     "bm" => "BERMUDA", 
     "bn" => "BRUNEI DARUSSALAM", 
     "bo" => "BOLIVIA", 
     "bu" => "BONAIRE, SAINT EUSTATIUS AND SABA", 
     "br" => "BRAZIL", 
     "bs" => "BAHAMAS", 
     "bt" => "BHUTAN", 
     "bv" => "BOUVET ISLAND", 
     "bw" => "BOTSWANA", 
     "by" => "BELARUS", 
     "bz" => "BELIZE", 
     "ca" => "CANADA", 
     "cc" => "COCOS (KEELING) ISLANDS", 
     "cd" => "CONGO", 
     "cf" => "CENTRAL AFRICAN REPUBLIC", 
     "cg" => "REPUBLIC OF THE CONGO", 
     "ch" => "SWITZERLAND", 
     "ci" => "COTE D?VOIRE", 
     "ck" => "COOK ISLANDS", 
     "cl" => "CHILE", 
     "cm" => "CAMEROON", 
     "cn" => "CHINA", 
     "co" => "COLOMBIA", 
     "cr" => "COSTA RICA", 
     "cu" => "CUBA", 
     "cv" => "CAPE VERDE", 
     "cw" => "CURACAO", 
     "cx" => "CHRISTMAS ISLAND", 
     "cy" => "CYPRUS", 
     "cz" => "CZECH REPUBLIC", 
     "de" => "GERMANY", 
     "dj" => "DJIBOUTI", 
     "dk" => "DENMARK", 
     "dm" => "DOMINICA", 
     "do" => "DOMINICAN REPUBLIC", 
     "dz" => "ALGERIA", 
     "ec" => "ECUADOR", 
     "ee" => "ESTONIA", 
     "eg" => "EGYPT", 
     "eh" => "WESTERN SAHARA", 
     "er" => "ERITREA", 
     "eu" => "EUROPEAN UNION", 
     "es" => "SPAIN", 
     "et" => "ETHIOPIA", 
     "fi" => "FINLAND", 
     "fj" => "FIJI", 
     "fk" => "FALKLAND ISLANDS", 
     "fm" => "MICRONESIA", 
     "fo" => "FAROE ISLANDS", 
     "fr" => "FRANCE", 
     "ga" => "GABON", 
     "gb" => "UNITED KINGDOM", 
     "gd" => "GRENADA", 
     "ge" => "GEORGIA", 
     "gf" => "FRENCH GUIANA", 
     "gg" => "GUERNSEY", 
     "gh" => "GHANA", 
     "gi" => "GIBRALTAR", 
     "gl" => "GREENLAND", 
     "gm" => "THE GAMBIA", 
     "gn" => "GUINEA", 
     "gp" => "GUADELOUPE", 
     "gq" => "EQUATORIAL GUINEA", 
     "gr" => "GREECE", 
     "gs" => "SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS", 
     "gt" => "GUATEMALA", 
     "gu" => "GUAM", 
     "gw" => "GUINEA-BISSAU", 
     "gy" => "GUYANA", 
     "hk" => "HONG KONG", 
     "hn" => "HONDURAS", 
     "hr" => "CROATIA", 
     "ht" => "HAITI", 
     "hu" => "HUNGARY", 
     "id" => "INDONESIA", 
     "ie" => "IRELAND", 
     "il" => "ISRAEL", 
     "im" => "ISLE OF MAN", 
     "in" => "INDIA", 
     "io" => "BRITISH INDIAN OCEAN TERRITORY", 
     "iq" => "IRAQ", 
     "ir" => "IRAN", 
     "is" => "ICELAND", 
     "it" => "ITALY", 
     "je" => "JERSEY", 
     "jm" => "JAMAICA", 
     "jo" => "JORDAN", 
     "jp" => "JAPAN", 
     "ke" => "KENYA", 
     "kg" => "KYRGYZSTAN", 
     "kh" => "CAMBODIA", 
     "ki" => "KIRIBATI", 
     "km" => "COMOROS", 
     "kn" => "SAINT KITTS AND NEVIS", 
     "kp" => "KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF", 
     "kr" => "SOUTH KOREA", 
     "kw" => "KUWAIT", 
     "ky" => "CAYMAN ISLANDS", 
     "kz" => "KAZAKHSTAN", 
     "la" => "LAOS", 
     "lb" => "LEBANON", 
     "lc" => "SAINT LUCIA", 
     "li" => "LIECHTENSTEIN", 
     "lk" => "SRI LANKA", 
     "lr" => "LIBERIA", 
     "ls" => "LESOTHO", 
     "lt" => "LITHUANIA", 
     "lu" => "LUXEMBOURG", 
     "lv" => "LATVIA", 
     "ly" => "LIBYA", 
     "ma" => "MOROCCO", 
     "mc" => "MONACO", 
     "md" => "MOLDOVA", 
     "me" => "MONTENEGRO", 
     "mf" => "SAINT MARTIN (FRENCH PART)", 
     "mg" => "MADAGASCAR", 
     "mh" => "MARSHALL ISLANDS", 
     "mk" => "REPUBLIC OF MACEDONIA", 
     "ml" => "MALI", 
     "mm" => "MYANMAR", 
     "mn" => "MONGOLIA", 
     "mo" => "MACAO", 
     "mp" => "NORTHERN MARIANA ISLANDS", 
     "mq" => "MARTINIQUE", 
     "mr" => "MAURITANIA", 
     "ms" => "MONTSERRAT", 
     "mt" => "MALTA", 
     "mu" => "MAURITIUS", 
     "mv" => "MALDIVES", 
     "mw" => "MALAWI", 
     "mx" => "MEXICO", 
     "my" => "MALAYSIA", 
     "mz" => "MOZAMBIQUE", 
     "na" => "NAMIBIA", 
     "nc" => "NEW CALEDONIA", 
     "ne" => "NIGER", 
     "nf" => "NORFOLK ISLAND", 
     "ng" => "NIGERIA", 
     "ni" => "NICARAGUA", 
     "nl" => "NETHERLANDS", 
     "no" => "NORWAY", 
     "np" => "NEPAL", 
     "nr" => "NAURU", 
     "nu" => "NIUE", 
     "nz" => "NEW ZEALAND", 
     "om" => "OMAN", 
     "pa" => "PANAMA", 
     "pe" => "PERU", 
     "pf" => "FRENCH POLYNESIA", 
     "pg" => "PAPUA NEW GUINEA", 
     "ph" => "PHILIPPINES", 
     "pk" => "PAKISTAN", 
     "pl" => "POLAND", 
     "pm" => "SAINT PIERRE AND MIQUELON", 
     "pn" => "PITCAIRN ISLANDS", 
     "pr" => "PUERTO RICO", 
     "ps" => "PALESTINIAN TERRITORY, OCCUPIED", 
     "pt" => "PORTUGAL", 
     "pw" => "PALAU", 
     "py" => "PARAGUAY", 
     "qa" => "QATAR", 
     "re" => "REUNION", 
     "ro" => "ROMANIA", 
     "rs" => "SERBIA", 
     "ru" => "RUSSIA", 
     "rw" => "RWANDA", 
     "sa" => "SAUDI ARABIA", 
     "sb" => "SOLOMON ISLANDS", 
     "sc" => "SEYCHELLES", 
     "sd" => "SUDAN", 
     "se" => "SWEDEN", 
     "sg" => "SINGAPORE", 
     "sh" => "SAINT HELENA", 
     "si" => "SLOVENIA", 
     "sj" => "SVALBARD AND JAN MAYEN", 
     "sk" => "SLOVAKIA", 
     "sl" => "SIERRA LEONE", 
     "sm" => "SAN MARINO", 
     "sn" => "SENEGAL", 
     "so" => "SOMALIA", 
     "sr" => "SURINAME", 
     "st" => "SAO TOME AND PRINCIPE", 
     "su" => "RUSSIA", //ex-USSR, let's presume it's russia 
     "sv" => "EL SALVADOR", 
     "sx" => "SINT MAARTEN (DUTCH PART)", 
     "sy" => "SYRIA", 
     "sz" => "SWAZILAN", 
     "tc" => "TURKS AND CAICOS ISLANDS", 
     "td" => "CHAD", 
     "tf" => "FRENCH SOUTHERN TERRITORIES", 
     "tg" => "TOGO", 
     "th" => "THAILAND", 
     "tj" => "TAJIKISTAN", 
     "tk" => "TOKELAU", 
     "tl" => "EAST TIMOR", 
     "tm" => "TURKMENISTAN", 
     "tn" => "TUNISIA", 
     "to" => "TONGA", 
     "tp" => "EAST TIMOR", 
     "tr" => "TURKEY", 
     "tt" => "TRINIDAD AND TOBAGO", 
     //"tv" => "TUVALU", don't include it here - it conflicts with .tv domain! 
     "tw" => "TAIWAN", 
     "tz" => "TANZANIA", 
     "ua" => "UKRAINE", 
     "ug" => "UGANDA", 
     "uk" => "UNITED KINGDOM", 
     "um" => "UNITED STATES MINOR OUTLYING ISLAND", 
     "us" => "UNITED STATES", 
     "uy" => "URUGUAY", 
     "uz" => "UZBEKISTAN", 
     "va" => "VATICAN CITY STATE", 
     "vc" => "SAINT VINCENT AND THE GRENADINES", 
     "ve" => "VENEZUELA", 
     "vg" => "BRITISH VIRGIN ISLANDS", 
     "vi" => "U.S. VIRGIN ISLANDS", 
     "vn" => "VIETNAM", 
     "vu" => "VANUATU", 
     "wf" => "WALLIS AND FUTUNA", 
     "ws" => "SAMOA", 
     "ye" => "YEMEN", 
     "yt" => "MAYOTTE", 
     "yu" => "YUGOSLAVIA", 
     "za" => "SOUTH AFRICA", 
     "zm" => "ZAMBIA", 
     "zw" => "ZIMBABWE" 
     ); 

    $country = $countries[strtolower($country_code)]; 
    if ($country == "" && !$b_very_strict) 
     $country = $country_code; //return at least something 

    return $country; 
} 

Наслаждайтесь!

Смежные вопросы