使用PHP來獲取用戶端和伺服器端IP

2020-07-16 10:05:41
1、php獲取用戶端IP

在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其它相關文章!