在PHP獲取用戶端IP時,常使用 $_SERVER["REMOTE_ADDR"] 。但如果用戶端是使用代理伺服器來存取,那取到的是代理伺服器的 IP 地址,而不是真正的用戶端 IP 地址。要想透過代理伺服器取得用戶端的真實 IP 地址,就要使用$_SERVER["HTTP_X_FORWARDED_FOR"]來讀取。
但只有用戶端使用「透明代理」的情況下,$_SERVER["HTTP_X_FORWARDED_FOR"] 的值才是用戶端真正的IP(如果是多層代理,該值可能是由用戶端真正IP和多個代理伺服器的IP組成,由逗號「,」分隔);而在「匿名代理」、「欺騙性代理」的情況下是代理伺服器的IP值(如果是多層代理,該值可能由多個代理伺服器的IP組成,由逗號「,」分隔);在「高匿名代理」的情況下是空值。
REMOTE_ADDR 是你的用戶端跟你的伺服器「握手」時候的IP。如果使用了「匿名代理」,REMOTE_ADDR將顯示代理伺服器的IP。
HTTP_CLIENT_IP 是代理伺服器傳送的HTTP頭。如果是「超級匿名代理」,則返回none值。同樣,REMOTE_ADDR也會被替換為這個代理伺服器的IP。
$_SERVER['REMOTE_ADDR']; //存取端IP(有可能是使用者,有可能是代理伺服器的,也有可能是反向代理伺服器的)
$_SERVER['HTTP_CLIENT_IP']; //代理端的(有可能存在,可偽造),未成標準,不一定伺服器都實現了。
$_SERVER['HTTP_X_FORWARDED_FOR']; //使用者是在哪個IP使用的代理(有可能存在,也可以偽造),有標準定義,用來識別經過HTTP代理後的用戶端IP地址,格式:clientip,proxy1,proxy2。詳細解釋見 http://zh.wikipedia.org/wiki/X-Forwarded-For。
三個值區別如下:
一、沒有使用代理伺服器的情況:
REMOTE_ADDR = 您的 IP
HTTP_VIA = 沒數值或不顯示
HTTP_X_FORWARDED_FOR = 沒數值或不顯示
二、使用透明代理伺服器的情況:Transparent Proxies
REMOTE_ADDR = 最後一個代理伺服器 IP
HTTP_VIA = 代理伺服器 IP
HTTP_X_FORWARDED_FOR = 您的真實 IP ,經過多個代理伺服器時,這個值類似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。
這類代理伺服器還是將您的資訊轉發給您的存取物件,無法達到隱藏真實身份的目的。
三、使用普通匿名代理伺服器的情況:Anonymous Proxies
REMOTE_ADDR = 最後一個代理伺服器 IP
HTTP_VIA = 代理伺服器 IP
HTTP_X_FORWARDED_FOR = 代理伺服器 IP ,經過多個代理伺服器時,這個值類似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。
隱藏了您的真實IP,但是向存取物件透露了您是使用代理伺服器存取他們的。
四、使用欺騙性代理伺服器的情況:Distorting Proxies
REMOTE_ADDR = 代理伺服器 IP
HTTP_VIA = 代理伺服器 IP
HTTP_X_FORWARDED_FOR = 隨機的 IP ,經過多個代理伺服器時,這個值類似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。
告訴了存取物件您使用了代理伺服器,但編造了一個虛假的隨機IP代替您的真實IP欺騙它。
五、使用高匿名代理伺服器的情況:High Anonymity Proxies (Elite proxies)
REMOTE_ADDR = 代理伺服器 IP
HTTP_VIA = 沒數值或不顯示
HTTP_X_FORWARDED_FOR = 沒數值或不顯示 ,經過多個代理伺服器時,這個值類似如下:203.98.182.163, 203.98.182.163, 203.129.72.215。
完全用代理伺服器的資訊替代了您的所有資訊,就象您就是完全使用那台代理伺服器直接存取物件。
範例程式碼:
//獲取使用者IP, 定義一個函數getIP() function getClientIP(){ if (getenv("HTTP_CLIENT_IP")) { $ip = getenv("HTTP_CLIENT_IP"); }elseif(getenv("HTTP_X_FORWARDED_FOR")) { $ip = getenv("HTTP_X_FORWARDED_FOR"); }elseif(getenv("REMOTE_ADDR")) { $ip = getenv("REMOTE_ADDR"); else $ip = "Unknow"; } return $ip; } 或者 function getClientIp() { $ip = 'unknow'; foreach (array( 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key) { if (array_key_exists($key, $_SERVER)) { foreach (explode(',', $_SERVER[$key]) as $ip) { $ip = trim($ip); //會過濾掉保留地址和私有地址段的IP,例如 127.0.0.1會被過濾 //也可以修改成正則驗證IP if ((bool) filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { return $ip; } } } } return $ip; }
2.php獲取伺服器端IP
伺服器端IP相關的變數
a. $_SERVER["SERVER_NAME"],需要使用函數gethostbyname()獲得。這個變數無論在伺服器端還是用戶端均能正確顯示。
b. $_SERVER["SERVER_ADDR"],在伺服器端測試:127.0.0.1(這個與httpd.conf中BindAddress的設定值相關)。在用戶端測試結果正確。
/** * 獲取伺服器端IP地址 * @return string */ function getServerIp() { if (isset($_SERVER)) { if($_SERVER['SERVER_ADDR']) { $server_ip = $_SERVER['SERVER_ADDR']; } else { $server_ip = $_SERVER['LOCAL_ADDR']; } } else { $server_ip = getenv('SERVER_ADDR'); } return $server_ip; } 或者 function getServerIP(){ return gethostbyname($_SERVER["SERVER_NAME"]); }
更多相關問題請存取PHP中文網相關問題教學:https://www.php.cn/
以上就是使用PHP來獲取用戶端和伺服器端IP的詳細內容,更多請關注TW511.COM其它相關文章!