我希望能够使用 PHP 在我的网站上检测访问者来自哪个国家/地区。
请注意,我并没有试图将其用作安全措施或任何重要的事情,只是改变一些单词的拼写(美国人似乎认为“注册”这个词有 2 个 Ls ....也许在“选择您的国家”列表中提供默认选项。
因此,使用地理定位数据库有点过头了,我真的不想为此而安装新的 PHP 库,那么找到访问者来自哪个国家/地区的最简单/最简单的方法是什么?
$_SERVER['HTTP_ACCEPT_LANGUAGE']
自 5.3.0 起,PHP 提供了一个函数来将变量解析为语言环境。
$locale = Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']);
echo $locale; // returns "en_US"
不能保证,但大多数浏览器都会提交一个 Accept-Language HTTP 标头,如果它们来自美国,则指定 en-us。不过,一些较旧的浏览器只说它们是 en。并非所有机器都正确设置以指示他们喜欢哪种语言环境。但这是一个很好的初步猜测。
基于English-UK 的用户通常将他们的系统或用户区域设置为English-UK,在默认浏览器配置中应该将en-gb 作为Accept Language 标头。(这个的早期版本说 en-uk;那是一个错字,抱歉。)其他国家也有 en 语言环境,例如 en-za(南非),而且,主要从理论上讲,像 en-jp 这样的组合也是可能的。
然而,基于 Geo-IP 的猜测在首选语言/区域设置上不太可能是正确的。Google 认为基于 IP 地址地理位置的内容协商是有道理的,当我在日本或韩国时,这真的让我很恼火......
您可以查看大多数浏览器将发送的HTTP_ACCEPT_LANGUAGE
标头(来自)。$_SERVER
以Zend_Locale为例,或者您甚至可能想要使用 lib。
您可以在没有整个库的情况下进行一些 IP比较。
使用 API,这样您就不需要任何东西。这是一个让您了解国家/地区的 Web API:
Example: http://api.hostip.info/get_html.php?ip=12.215.42.19
Return : Country: UNITED STATES (US)
但是,你有没有想过使用浏览器代理语言?您也许可以从中知道英语的类型。
这个名为BlockCountry的网站可让您按国家/地区列出 IP。当然,您不想阻止,但您可以使用 IP 列表并比较它们(获取所有美国 IP...)这可能不准确...
鉴于您声明的目的,Accept-Language 标头是比基于 IP 的地理定位更合适的解决方案。事实上,这正是 Accept-Language 的预期目的。
解析$_SERVER["HTTP_ACCEPT_LANGUAGE"]
以获取国家和浏览器的语言环境。
我使用 HTTP_ACCEPT_LANGUAGE
$localePreferences = explode(",",$_SERVER['HTTP_ACCEPT_LANGUAGE']);
if(is_array($localePreferences) && count($localePreferences) > 0) {
$browserLocale = $localePreferences[0];
$_SESSION['browser_locale'] = $browserLocale;
}
为了识别您的访问者国家/地区,我使用了GeoIP扩展,使用起来非常简单。
http://countries.nerd.dk服务是我用于 IP 到国家/地区映射的服务。它工作得非常好,并且基于 DNS,缓存也很好。
如果您不想依赖外部服务,也可以下载数据库以供本地使用。
GeoIP 扩展是不错的选择。
或者您可以执行以下操作:
从http://www.maxmind.com/app/geoip_country下载“geoip.dat”和 geoip.inc
在 geoip.inc 标题中,您将找到如何使用它(例如初始化和其余的......)
一件事是观看者想要哪种语言,其次是您可以提供的服务:
$SystemLocales = explode("\n", shell_exec('locale -a'));
$BrowserLocales = explode(",",str_replace("-","_",$_SERVER["HTTP_ACCEPT_LANGUAGE"])); // brosers use en-US, Linux uses en_US
for($i=0;$i<count($BrowserLocales);$i++) {
list($BrowserLocales[$i])=explode(";",$BrowserLocales[$i]); //trick for "en;q=0.8"
for($j=0;$j<count($SystemLocales);$j++) {
if ($BrowserLocales[$i]==substr($SystemLocales[$j],0,strlen($BrowserLocales[$i]))){
setlocale(LC_ALL, $SystemLocales[$j]);
break 2; // found and set, so no more check is needed
}
}
}
例如,我的系统仅服务于:
我的浏览器语言是:pl、en-US、en => 所以唯一正确的语言环境是 pl_PL.UTF-8。
当没有找到成功的比较时 - 根本没有 setlocale。