function getClientIP() {
if (isset($_SERVER)) {
if (isset($_SERVER["HTTP_X_FORWARDED_FOR"]))return $_SERVER["HTTP_X_FORWARDED_FOR"];
if (isset($_SERVER["HTTP_CLIENT_IP"]))return $_SERVER["HTTP_CLIENT_IP"];
return $_SERVER["REMOTE_ADDR"];}
if (getenv('HTTP_X_FORWARDED_FOR'))return getenv('HTTP_X_FORWARDED_FOR');
if (getenv('HTTP_CLIENT_IP'))return getenv('HTTP_CLIENT_IP');
return getenv('REMOTE_ADDR');}
class RemoteAddress{/*** Whether to use proxy addresses or not.** As default this setting is disabled - IP address is mostly needed to increase* security. HTTP_* are not reliable since can easily be spoofed. It can be enabled* just for more flexibility, but if user uses proxy to connect to trusted services* it's his/her own risk, only reliable field for IP address is $_SERVER['REMOTE_ADDR'].** @var bool*/protected $useProxy = false;
/*** List of trusted proxy IP addresses** @var array*/protected $trustedProxies = array();
/*** HTTP header to introspect for proxies** @var string*/protected $proxyHeader = 'HTTP_X_FORWARDED_FOR';
// [...]
/*** Returns client IP address.** @return string IP address.*/public function getIpAddress(){$ip = $this->getIpAddressFromProxy();if ($ip) {return $ip;}
// direct IP addressif (isset($_SERVER['REMOTE_ADDR'])) {return $_SERVER['REMOTE_ADDR'];}
return '';}
/*** Attempt to get the IP address for a proxied client** @see http://tools.ietf.org/html/draft-ietf-appsawg-http-forwarded-10#section-5.2* @return false|string*/protected function getIpAddressFromProxy(){if (!$this->useProxy|| (isset($_SERVER['REMOTE_ADDR']) && !in_array($_SERVER['REMOTE_ADDR'], $this->trustedProxies))) {return false;}
$header = $this->proxyHeader;if (!isset($_SERVER[$header]) || empty($_SERVER[$header])) {return false;}
// Extract IPs$ips = explode(',', $_SERVER[$header]);// trim, so we can compare against trusted proxies properly$ips = array_map('trim', $ips);// remove trusted proxy IPs$ips = array_diff($ips, $this->trustedProxies);
// Any left?if (empty($ips)) {return false;}
// Since we've removed any known, trusted proxy servers, the right-most// address represents the first IP we do not know about -- i.e., we do// not know if it is a proxy server, or a client. As such, we treat it// as the originating IP.// @see http://en.wikipedia.org/wiki/X-Forwarded-For$ip = array_pop($ips);return $ip;}
// [...]}
if (($ip=filter_input(INPUT_SERVER, 'REMOTE_ADDR', validate_ip)) === false or empty($ip)) {exit;}echo $ip;
PS
if (($ip=filter_input(INPUT_SERVER, 'REMOTE_ADDR', FILTER_VALIDATE_IP|FILTER_FLAG_NO_PRIV_RANGE|FILTER_FLAG_NO_RES_RANGE)) === false) {header('HTTP/1.0 400 Bad Request');exit;}
function get_ip_address() {
// Check for shared Internet/ISP IPif (!empty($_SERVER['HTTP_CLIENT_IP']) && validate_ip($_SERVER['HTTP_CLIENT_IP'])) {return $_SERVER['HTTP_CLIENT_IP'];}
// Check for IP addresses passing through proxiesif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
// Check if multiple IP addresses exist in varif (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 address since all else failedreturn $_SERVER['REMOTE_ADDR'];}
/*** Ensures an IP address is both a valid IP address 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 address is set and not equivalent to 255.255.255.255if ($ip !== false && $ip !== -1) {// Make sure to get unsigned long representation of IP address// 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 checkingif ($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;}
$ip = "";
if (!empty($_SERVER["HTTP_CLIENT_IP"])){// Check for IP address from shared Internet$ip = $_SERVER["HTTP_CLIENT_IP"];}elseif (!empty($_SERVER["HTTP_X_FORWARDED_FOR"])){// Check for the proxy user$ip = $_SERVER["HTTP_X_FORWARDED_FOR"];}else{$ip = $_SERVER["REMOTE_ADDR"];}echo $ip;
function valid_ip($ip) {// for list of reserved IP addresses, see https://en.wikipedia.org/wiki/Reserved_IP_addressesreturn $ip && substr($ip, 0, 4) != '127.' && substr($ip, 0, 4) != '127.' && substr($ip, 0, 3) != '10.' && substr($ip, 0, 2) != '0.' ? $ip : false;}
function get_client_ip() {// using explode to get only client ip from list of forwarders. see https://en.wikipedia.org/wiki/X-Forwarded-Forreturn@$_SERVER['HTTP_X_FORWARDED_FOR'] ? explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'], 2)[0] :@$_SERVER['HTTP_CLIENT_IP'] ? explode(',', $_SERVER['HTTP_CLIENT_IP'], 2)[0] :valid_ip(@$_SERVER['REMOTE_ADDR']) ?:'UNKNOWN';}
echo get_client_ip();
$ip = filter_input(INPUT_SERVER, 'HTTP_CLIENT_IP', FILTER_VALIDATE_IP)?: filter_input(INPUT_SERVER, 'HTTP_X_FORWARDED_FOR', FILTER_VALIDATE_IP)?: $_SERVER['REMOTE_ADDR']?? '0.0.0.0'; // Or other value fits "not defined" in your logic
<?php/*** Function to get the client ip address** @return string The Ip address*/function getIp(): string {if (! empty($_SERVER['HTTP_CLIENT_IP'])) {return $_SERVER['HTTP_CLIENT_IP'];}
if (! empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {return $_SERVER['HTTP_X_FORWARDED_FOR'];}
return $_SERVER['REMOTE_ADDR'] ?? '?';}
甚至更小
/*** Function to get the client ip address** @return string The Ip address*/function getIp(): string {return $_SERVER['HTTP_CLIENT_IP'] ?? $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? '';}
//Get client's IP or null if nothing looks validfunction ip_get($allow_private = false){//Place your trusted proxy server IPs here.$proxy_ip = ['127.0.0.1'];
//The header to look for (Make sure to pick the one that your trusted reverse proxy is sending or else you can get spoofed)$header = 'HTTP_X_FORWARDED_FOR'; //HTTP_CLIENT_IP, HTTP_X_FORWARDED, HTTP_FORWARDED_FOR, HTTP_FORWARDED
//If 'REMOTE_ADDR' seems to be a valid client IP, use it.if(ip_check($_SERVER['REMOTE_ADDR'], $allow_private, $proxy_ip)) return $_SERVER['REMOTE_ADDR'];
if(isset($_SERVER[$header])){//Split comma separated values [1] in the header and traverse the proxy chain backwards.//[1] https://en.wikipedia.org/wiki/X-Forwarded-For#Format$chain = array_reverse(preg_split('/\s*,\s*/', $_SERVER[$header]));foreach($chain as $ip) if(ip_check($ip, $allow_private, $proxy_ip)) return $ip;}
return null;}
//Check for valid IP. If 'allow_private' flag is set to truthy, it allows private IP ranges as valid client IP as well. (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)//Pass your trusted reverse proxy IPs as $proxy_ip to exclude them from being valid.function ip_check($ip, $allow_private = false, $proxy_ip = []){if(!is_string($ip) || is_array($proxy_ip) && in_array($ip, $proxy_ip)) return false;$filter_flag = FILTER_FLAG_NO_RES_RANGE;
if(!$allow_private){//Disallow loopback IP range which doesn't get filtered via 'FILTER_FLAG_NO_PRIV_RANGE' [1]//[1] https://www.php.net/manual/en/filter.filters.validate.phpif(preg_match('/^127\.$/', $ip)) return false;$filter_flag |= FILTER_FLAG_NO_PRIV_RANGE;}
return filter_var($ip, FILTER_VALIDATE_IP, $filter_flag) !== false;}
function getClientIP():string{$keys=array('HTTP_CLIENT_IP','HTTP_X_FORWARDED_FOR','HTTP_X_FORWARDED','HTTP_FORWARDED_FOR','HTTP_FORWARDED','REMOTE_ADDR');foreach($keys as $k){if (!empty($_SERVER[$k]) && filter_var($_SERVER[$k], FILTER_VALIDATE_IP)){return $_SERVER[$k];}}return "UNKNOWN";}
public static function getPublicIP() : string{$realIP = "Invalid IP Address";
$activeHeaders = [];
$headers = ["HTTP_CLIENT_IP","HTTP_PRAGMA","HTTP_XONNECTION","HTTP_CACHE_INFO","HTTP_XPROXY","HTTP_PROXY","HTTP_PROXY_CONNECTION","HTTP_VIA","HTTP_X_COMING_FROM","HTTP_COMING_FROM","HTTP_X_FORWARDED_FOR","HTTP_X_FORWARDED","HTTP_X_CLUSTER_CLIENT_IP","HTTP_FORWARDED_FOR","HTTP_FORWARDED","ZHTTP_CACHE_CONTROL","REMOTE_ADDR" #this should be the last option];
#Find active headersforeach ($headers as $key){if (array_key_exists($key, $_SERVER)){$activeHeaders[$key] = $_SERVER[$key];}}
#Reemove remote address since we got more options to choose fromif(count($activeHeaders) > 1){unset($activeHeaders["REMOTE_ADDR"]);}
#Pick a random item now that we have a secure way.$realIP = $activeHeaders[array_rand($activeHeaders)];
#Validate the public IPif (filter_var($realIP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)){return $realIP;}
return $realIP;}
/*** Gets, validates and returns the connecting client's IP*/function getClientIP(){
// Get real visitor IP behind CloudFlare networkif (!empty($_SERVER["HTTP_CF_CONNECTING_IP"]) && validateIP($_SERVER['HTTP_CF_CONNECTING_IP'])) {return $_SERVER["HTTP_CF_CONNECTING_IP"];}
// Get real visitor IP behind NGINX proxy - https://easyengine.io/tutorials/nginx/forwarding-visitors-real-ip/if (!empty($_SERVER["HTTP_X_REAL_IP"]) && validateIP($_SERVER['HTTP_X_REAL_IP'])) {return $_SERVER["HTTP_X_REAL_IP"];}
// Check for shared Internet/ISP IPif (!empty($_SERVER['HTTP_CLIENT_IP']) && validateIP($_SERVER['HTTP_CLIENT_IP'])) {return $_SERVER['HTTP_CLIENT_IP'];}
// Check for IP addresses passing through proxiesif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
// Check if multiple IP addresses exist in varif (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',') !== false) {$iplist = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);foreach ($iplist as $ip) {if (validateIP($ip))return $ip;}}else {if (validateIP($_SERVER['HTTP_X_FORWARDED_FOR']))return $_SERVER['HTTP_X_FORWARDED_FOR'];}}
if (!empty($_SERVER['HTTP_X_FORWARDED']) && validateIP($_SERVER['HTTP_X_FORWARDED']))return $_SERVER['HTTP_X_FORWARDED'];
if (!empty($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']) && validateIP($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']))return $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
if (!empty($_SERVER['HTTP_FORWARDED_FOR']) && validateIP($_SERVER['HTTP_FORWARDED_FOR']))return $_SERVER['HTTP_FORWARDED_FOR'];
if (!empty($_SERVER['HTTP_FORWARDED']) && validateIP($_SERVER['HTTP_FORWARDED']))return $_SERVER['HTTP_FORWARDED'];
// Return unreliable IP address since all else failedreturn $_SERVER['REMOTE_ADDR'];}
/*** Ensures an IP address is both a valid IP address and does not fall within* a private network range.*/function validateIP($ip) {
if (strtolower($ip) === 'unknown')return false;
// Generate IPv4 network address$ip = ip2long($ip);
// Do additional filtering on IPif(!filter_var($ip, FILTER_VALIDATE_IP))return false;
// If the IP address is set and not equivalent to 255.255.255.255if ($ip !== false && $ip !== -1) {
// Make sure to get unsigned long representation of IP address// 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 checkingif ($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;}