需要有关网站位置识别的帮助

时间:2010-11-11 19:44:50

标签: location

我有一个网站,我想让它识别用户的位置,并根据该用户将用户移动到正确的子域。 一个例子: 如果我从法国访问该网站,我希望它将我重定向到www.website.com/France 然后扔......

我该怎么办呢?

2 个答案:

答案 0 :(得分:0)

在应用程序服务器级别,您可以通过在ip-2-country数据库中查找来查找用户所在的国家/地区。它们通常是您从专门从事不同数据库的软件公司购买的产品,用于满足不同需求。

这是一个:ip2country

如果您有一个可以为您执行此操作的DNS提供程序,您也可以在dns级别执行此操作。这可能是对你最有意义的。然后您的访问者将立即被发送到最近的服务器,而不必首先联系“调度程序”服务器(DNS服务器将是路由器),然后正确的IP将在负责dns服务器的dns服务器之间以某种方式缓存域和DNS服务器一路上一直到用户。

答案 1 :(得分: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;
}

在使用上述功能之前,您需要使用以下功能编译数据库文件:

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>";
}

现在,如果您喜欢,可以使用下面的功能将2个字母的国家/地区代码转换为可读的国家/地区名称:

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;
}

享受!