我使用ip2location_db11.CSV数据库来查找详细的ips。它创建了一个这样的表:
CREATE TABLE `ip2location_db11`(
`ip_from` INT(10) UNSIGNED,
`ip_to` INT(10) UNSIGNED,
`country_code` CHAR(2),
`country_name` VARCHAR(64),
`region_name` VARCHAR(128),
`city_name` VARCHAR(128),
`latitude` DOUBLE,
`longitude` DOUBLE,
`zip_code` VARCHAR(30),
`time_zone` VARCHAR(8),
INDEX `idx_ip_from` (`ip_from`),
INDEX `idx_ip_to` (`ip_to`),
INDEX `idx_ip_from_to` (`ip_from`, `ip_to`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
并详细说明:
"16777216","16777471","AU","Australia","Queensland","Brisbane","-27.467940","153.028090","4000","+10:00"
cuz大量的ips所有ip位于2列的ip范围内(ip_from,ip_to)
如何从这张表中找到我的ip?我知道这个:
$result = mysql_query("SELECT *
FROM ip2location_db11
WHERE ip = {$_SERVER['REMOTE_ADDR']}
LIMIT 1") or die(mysql_error());
$row = mysql_fetch_assoc($result);
但是如何从列中的ip范围中找到我的ips(ip_from,ip_to)
答案 0 :(得分:1)
查看示例数据并根据ip的列类型判断我会说ip已经使用ip2long()转换为int,对于ipv4地址很好,对于ipv6我认为不太好。所以,你的sql将需要考虑ip2long转换,并且在php中有一些大数字的问题,所以我建议也使用sprintf。
$ip = sprintf( '%u', ip2long( $_SERVER['REMOTE_ADDR'] ) );
$sql= 'select * from `ip2location_db11` where `ip_from` >= '.$ip.' and `ip_to` <= '.$ip.' limit 1;';
答案 1 :(得分:0)
这是怎么回事:
$db = new PDO( "mysql:dbname=$dbname", $user, $pass, array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
) );
$sth = $db->prepare("
SELECT *
FROM ip2location_db11
WHERE ? BETWEEN ip_from AND ip_to
LIMIT 1
" );
$sth->execute( array(
array_reduce(
explode(".", $_SERVER['REMOTE_ADDR'] ),
function($carry,$in) { return ($carry *256) + intval( $in);}
)
) );
$row = $sth->fetch( \PDO::FETCH_ASSOC );
我在这里使用PDO,因为mysql
扩展名已弃用,并且不允许
参数化查询。
答案 2 :(得分:0)
INET_ATON(expr)
会将IP地址转换为数字值。
$ip = $_SERVER['REMOTE_ADDR'];
SELECT *
FROM ip2location_db11
WHERE ip_from >= INET_ATON('$ip')
AND ip_top <= INET_ATON('$ip')
LIMIT 1
参考:http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_inet-aton
答案 3 :(得分:0)
这是简单的查询
SELECT * FROM ip2location_db11 WHERE INET_ATON('xxx.xxx.xxx.xxx') BETWEEN ip_from AND ip_to