-
-
Save cballou/2201933 to your computer and use it in GitHub Desktop.
<?php | |
function get_ip_address() { | |
$ip_keys = array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR'); | |
foreach ($ip_keys as $key) { | |
if (array_key_exists($key, $_SERVER) === true) { | |
foreach (explode(',', $_SERVER[$key]) as $ip) { | |
// trim for safety measures | |
$ip = trim($ip); | |
// attempt to validate IP | |
if (validate_ip($ip)) { | |
return $ip; | |
} | |
} | |
} | |
} | |
return isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : false; | |
} | |
/** | |
* Ensures an ip address is both a valid IP and does not fall within | |
* a private network range. | |
*/ | |
function validate_ip($ip) | |
{ | |
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false) { | |
return false; | |
} | |
return true; | |
} |
<?php | |
/** | |
* Retrieves the best guess of the client's actual IP address. | |
* Takes into account numerous HTTP proxy headers due to variations | |
* in how different ISPs handle IP addresses in headers between hops. | |
*/ | |
function get_ip_address() { | |
// check for shared internet/ISP IP | |
if (!empty($_SERVER['HTTP_CLIENT_IP']) && validate_ip($_SERVER['HTTP_CLIENT_IP'])) { | |
return $_SERVER['HTTP_CLIENT_IP']; | |
} | |
// check for IPs passing through proxies | |
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { | |
// check if multiple ips exist in var | |
if (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',') !== false) { | |
$iplist = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); | |
foreach ($iplist as $ip) { | |
if (validate_ip($ip)) | |
return $ip; | |
} | |
} else { | |
if (validate_ip($_SERVER['HTTP_X_FORWARDED_FOR'])) | |
return $_SERVER['HTTP_X_FORWARDED_FOR']; | |
} | |
} | |
if (!empty($_SERVER['HTTP_X_FORWARDED']) && validate_ip($_SERVER['HTTP_X_FORWARDED'])) | |
return $_SERVER['HTTP_X_FORWARDED']; | |
if (!empty($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']) && validate_ip($_SERVER['HTTP_X_CLUSTER_CLIENT_IP'])) | |
return $_SERVER['HTTP_X_CLUSTER_CLIENT_IP']; | |
if (!empty($_SERVER['HTTP_FORWARDED_FOR']) && validate_ip($_SERVER['HTTP_FORWARDED_FOR'])) | |
return $_SERVER['HTTP_FORWARDED_FOR']; | |
if (!empty($_SERVER['HTTP_FORWARDED']) && validate_ip($_SERVER['HTTP_FORWARDED'])) | |
return $_SERVER['HTTP_FORWARDED']; | |
// return unreliable ip since all else failed | |
return $_SERVER['REMOTE_ADDR']; | |
} | |
/** | |
* Ensures an ip address is both a valid IP and does not fall within | |
* a private network range. | |
*/ | |
function validate_ip($ip) { | |
if (strtolower($ip) === 'unknown') | |
return false; | |
// generate ipv4 network address | |
$ip = ip2long($ip); | |
// if the ip is set and not equivalent to 255.255.255.255 | |
if ($ip !== false && $ip !== -1) { | |
// make sure to get unsigned long representation of ip | |
// due to discrepancies between 32 and 64 bit OSes and | |
// signed numbers (ints default to signed in PHP) | |
$ip = sprintf('%u', $ip); | |
// do private network range checking | |
if ($ip >= 0 && $ip <= 50331647) return false; | |
if ($ip >= 167772160 && $ip <= 184549375) return false; | |
if ($ip >= 2130706432 && $ip <= 2147483647) return false; | |
if ($ip >= 2851995648 && $ip <= 2852061183) return false; | |
if ($ip >= 2886729728 && $ip <= 2887778303) return false; | |
if ($ip >;= 3221225984 && $ip <= 3221226239) return false; | |
if ($ip >;= 3232235520 && $ip <= 3232301055) return false; | |
if ($ip >= 4294967040) return false; | |
} | |
return true; | |
} |
I insert REMOTE_ADDR in one column, then I loop through the possible proxy address keys in $_SERVER and when I find one, it gets logged to the Proxy column.
Thank you so much cballou, you saved me from spammer which views my blog articles and increments my counter redundantly. With this code, now I can use an advanced counter based IP address. But why doesn't $_SERVER['REMOTE_ADDR'] work as a single? It gives me just hosting IP address, not users' which views my website. Could you explain this situtation?
what does >;= mean on lines 63-64?
/**
* Function to get the client ip address
* @return String|false
*/
function get_ip_address() {
$ip_keys = array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR');
foreach ($ip_keys as $key) {
if (array_key_exists($key, $_SERVER) === true) {
foreach (explode(',', $_SERVER[$key]) as $ip) {
// trim for safety measures
$ip = trim($ip);
// attempt to validate IP
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false) {
return $ip;
}
}
}
}
return isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : false;
}
Small typo:
if ($ip >;= 3221225984 && $ip <= 3221226239) return false;
if ($ip >;= 3232235520 && $ip <= 3232301055) return false;
should be:
if ($ip >= 3221225984 && $ip <= 3221226239) return false;
if ($ip >= 3232235520 && $ip <= 3232301055) return false;
<?php
//Mainly, $_SERVER['REMOTE_ADDR'] contains IP address of client who viewing the page
function get_client_ip($single = 2) {
$ipaddress = array();
if( $single == 2){
if (isset($_SERVER['HTTP_CLIENT_IP']))
$ipaddress[] = $_SERVER['HTTP_CLIENT_IP'];
if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
$ipaddress[] = $_SERVER['HTTP_X_FORWARDED_FOR'];
if(isset($_SERVER['HTTP_X_FORWARDED']))
$ipaddress[] = $_SERVER['HTTP_X_FORWARDED'];
if(isset($_SERVER['HTTP_FORWARDED_FOR']))
$ipaddress[] = $_SERVER['HTTP_FORWARDED_FOR'];
if(isset($_SERVER['HTTP_FORWARDED']))
$ipaddress[] = $_SERVER['HTTP_FORWARDED'];
if(isset($_SERVER['REMOTE_ADDR']))
$ipaddress[] = $_SERVER['REMOTE_ADDR'];
if(count($ipaddress) == 0)
$ipaddress[] = 'UNKNOWN';
$ips = implode(", ", array_unique($ipaddress));
}
if( $single == 1){
$ips = $_SERVER['REMOTE_ADDR'];
}
return $ips;
}
?>
source: https://standingtech.com/clientip/how-to-get-client-ip-address-in-php
This is incorrect thinking. ↑
REMOTE_ADDR
should be first in the above code, not last and marked as "unreliable".All I have to do is set a
HTTP_X_FORWARDED_FOR
header and your server will log whatever IP I give it.Background: These are valid headers that some proxies do pass - but you have to take their word for it. Anyone could claim anything and you have no idea if it's true.
You MUST log the
REMOTE_ADDR
since it's the only guaranteed address. If you want to log these others as additional information then please do it - but don't ignoreREMOTE_ADDR
.