我有一个网站,我想让它识别用户的位置,并根据该用户将用户移动到正确的子域。 一个例子: 如果我从法国访问该网站,我希望它将我重定向到www.website.com/France 然后扔......
我该怎么办呢?
答案 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;
}
享受!