Ich hatte diesen Code herum. Es ist eine Weile her und ich kann mich nicht mehr an einige Entscheidungen erinnern, aber ich versichere Ihnen, dass es gründlich getestet wurde
(eigentlich habe ich es nur ein wenig verändert, Variablen umbenannt und Kommentare hinzugefügt, also ist es möglich, dass ich einfach kaputt gegangen bin es :)
Sie können die get_ip_addr
und is_private_ip_addr
Funktionen nützlich finden.
get_ip_addr
kann sowohl eine IP-Adresse als auch einen Hostnamen annehmen.
<?php
function get_ip_addr($host){
$long_ipaddr = my_ip2long($host);
$host = trim($host);
if($long_ipaddr !== false){
$str_ip = long2ip($long_ipaddr); // Because of e.g. 245.254.245
return $str_ip;
}
$ip_addr = @gethostbyname($host);
if($ip_addr and $ip_addr != -1 ){
return $ip_addr;
}
return false;
}
function my_ip2long($ipaddr){
$long_ip = ip2long($ipaddr);
if($long_ip === false){
return false;
}
// http://php.net/manual/en/function.ip2long.php says:
// Note:
// Because PHP's integer type is signed, and many IP addresses
// will result in negative integers, you need to use
// the "%u" formatter of sprintf() or printf() to get
// the string representation of the unsigned IP address.
$long_ip = sprintf("%u", $long_ip);
return $long_ip;
}
function ip2bin($ip){
$octets = explode(".", $ip);
foreach($octets as $k => $v){
$octets[$k] = str_pad(decbin($v), 8, "0", STR_PAD_LEFT);
}
return implode('', $octets);
}
function ip_in_range($ip, $prefix, $mask_len){
$ip = ip2bin($ip);
$prefix = ip2bin($prefix);
$ip = substr($ip, 0, $mask_len);
$prefix = substr($prefix, 0, $mask_len);
// Watch out! Two numerical strings are converted to integers
// when you use ==. This is trouble for long integers.
// Using === skips this behaviour
return ($ip === $prefix);
}
function is_private_ip_addr($ipaddr){
if("localhost" === $ipaddr) return true;
$long_ipaddr = my_ip2long($ipaddr);
if($long_ipaddr === false){
return false; // Shouldn't be calling this!
}
// Info below obtained from http://bugs.php.net/bug.php?id=47435#c145655
// Not sure why 127.0.0.0/8 isn't mentioned ...?
// Also, in IPv6 there's the multicast address range: ff00::/8s
//
// IPv4 private ranges
// 10.0.0.0/8 // private use network (rfc1918)
// 172.16.0.0/12 // private use network (rfc1918)
// 192.168.0.0/16 // private use network (rfc1918)
//
// IPv4 reserved ranges
// 0.0.0.0/8 // "this" network (rfc1700)
// 169.254.0.0/16 // link local network (rfc3927)
// 192.0.2.0/24 // test net (rfc3330)
// 224.0.0.0/4 // Multicast (rfc3171)
// 240.0.0.0/4 // Reserved for Future Use (rfc1700)
//
// IPv6 Private range
// fc00::/7 // unique-local addresses (rfc4193)
//
// IPv6 Reserved ranges
// ::/128 // unspecified address (rfc4291)
// ::1/128 // loopback address (rfc4291)
// fe80::/10 // link local unicast (rfc4291)
// 2001:db8::/32 // documentation addresses (rfc3849)
// 5f00::/8 // 6Bone
// 3ffe::/16 // 6Bone
// ::ffff:0:0/96 // IPv4-Mapped addresses (rfc4291)
// 2001:10::/28 // ORCHID addresses (rfc4843)
// ::/0 // default unicast route address
//
// Anyways, this are the relevant RFCs:
// RFC 3330 (Sep 2002), "Special-Use IPv4 Addresses":
// see section 3 for a nice table
// RFC 5156 (Apr 2008), "Special-Use IPv6 Addresses"
//
// Also, this function currently only deals with IPv4 addresses,
// since PHP's ip2long simply doesn't support IPv6 anyway.
// You can't currently even trust long ints to have 64 bit,
// so a 128 bit long int is out of the question.
if(ip_in_range($ipaddr, "127.0.0.0", 8)) return true; // Loopback
if(ip_in_range($ipaddr, "10.0.0.0", 8)) return true; // Private addresses (Class A range)
if(ip_in_range($ipaddr, "172.16.0.0", 12)) return true; // Private addresses (Class B range)
if(ip_in_range($ipaddr, "192.168.0.0", 16)) return true; // Private addresses (Class C range)
if(ip_in_range($ipaddr, "169.254.0.0", 16)) return true; // "This" network
if(ip_in_range($ipaddr, "192.0.2.0", 24)) return true; // "TEST-NET" (documentation and examples)
if(ip_in_range($ipaddr, "224.0.0.0", 4)) return true; // Multicast
if(ip_in_range($ipaddr, "240.0.2.0", 4)) return true; // Reserved for future use
return false;
}
Sie können diesen Code betrachten unter einer permissiven CC BY-SA freigegeben.
Tun Sie, was Sie wollen, aber wenn Sie es verbessern, sagen Sie uns bitte hier darüber.
Ich markiere diesen Beitrag Community Wiki ..
Was ist die Datenquelle? Apache-Zugriffsprotokoll? – stillstanding
Die IP wurde von $ _SERVER abgerufen und in einer MySQL-Datenbank gespeichert. – HappyDeveloper