我正在开发一个用于第三方网站的开源插件。它包含以下代码片段,用于获取访问者的国家代码:
$visitorIP = $_SERVER['REMOTE_ADDR'];
if( filter_var($visitorIP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) ) {
$geoIPdb = 'GeoIP.dat';
} elseif ( filter_var($visitorIP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) ) {
$geoIPdb = 'GeoIPv6.dat';
} else return 'something';
include_once($this->maxmindDirectory . 'geoip.inc');
$gi = geoip_open($this->maxmindDirectory . $geoIPdb, GEOIP_STANDARD);
if($geoIPdb == 'GeoIP.dat') {
$ISOcode = geoip_country_code_by_addr($gi, $visitorIP); }
else {
$ISOcode = geoip_country_code_by_addr_v6($gi, $visitorIP);
}
我的服务器和ISP都使用IPv4,代码适用于IPv4地址;但我无法测试真实的访问者IPv6地址。
然而,如果我通过硬编码$visitorIP
作为IPv6地址进行测试,我得到一个"inet_pton()[函数。[/p]:未识别的地址"警告。
这是我的代码错误,还是我的服务器/PHP配置?(当我检查AF_INET6是未定义的)
如果它不是我的错误,这段代码将在服务器上正确工作,其中$_SERVER['REMOTE_ADDR']包含IPv6地址,或者我还需要添加额外的检查?
谢谢你的建议
你的服务器的PHP编译没有IPv6支持(使用--disable-ipv6
),所以你的代码失败,但它应该工作良好的服务器上的PHP支持IPv6
if (defined('AF_INET6')) {
echo "PHP was compiled without --disable-ipv6 option";
} else {
echo "PHP was compiled with --disable-ipv6 option";
}
顺便说一下,这是我如何重写你的代码,它看起来更好,但我远不是一个PHP专家,所以使用它你自己承担风险。
function getISOcode($visitorIP) {
if(filter_var($visitorIP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
$geoIPdb = "GeoIP.dat";
include_once($this->maxmindDirectory."geoip.inc");
$gi = geoip_open($this->maxmindDirectory.$geoIPdb, GEOIP_STANDARD);
return geoip_country_code_by_addr($gi, $visitorIP);
} elseif (filter_var($visitorIP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
$geoIPdb = "GeoIPv6.dat";
include_once($this->maxmindDirectory."geoip.inc");
$gi = geoip_open($this->maxmindDirectory.$geoIPdb, GEOIP_STANDARD);
return geoip_country_code_by_addr($gi, $visitorIP);
} else {
return false; // or throw an exception about the address being invalid
}
}