因為近日需要幾個小項目上CDN,但上CDN的同時,要獲取到用戶的真實IP地址。雖然網上有很多關于網站在CDN加速的情況下,PHP獲取用戶真實IP地址的方法,但總覺的不可靠,還是自己測試一下最好。

使用CDN后,PHP如何獲取用戶的真是IP

PHP超全局變量$_SERVER

PHP超全局變量$_SERVER,是一個包含了諸如頭信息(header)、路徑(path)、以及腳本位置(script locations)等等信息的數組,這個數組中也包含了用戶的請求的真實IP址址,所以我們可以利用它在使用各種cdn加速網站上進行測試。

在php中,一般都是通過以下代碼來獲取真實IP地址,但在CDN下,此代碼獲取到的IP只是CDN最近一個節點的IP,并不是真實的用戶IP

<?php
$_SERVER['REMOTE_ADDR'];
?>

編寫一個如下代碼的PHP文件,并命名為 ceshi.php 并放到使用CDN加速的網站根目錄下面,并在瀏覽器中以網址的方式打開。

代碼:

<?php
print_r($_SERVER);
?>

以下是使用各個CDN加速后,打印出的結果,我們只列出含有真實IP地址的部份與 'REMOTE_ADDR' 部份

百度CDN打印結果:

Array
(   
    [HTTP_X_FORWARDED_FOR] => 119.164.27.53,123.234.0.103,27.221.124.94
    [HTTP_X_REAL_IP] => 119.164.27.53
    [REMOTE_ADDR] => 150.138.138.169
    .........
)

注意:

119.164.27.53 為我自己的真實IP,所以在百度CDN下打印出來的數組,只有 [HTTP_X_FORWARDED_FOR] 與 [HTTP_X_REAL_IP]  包含了真實的IP地址.

阿里CDN打印結果:

Array
(
    [HTTP_ALI_CDN_REAL_IP] => 119.164.27.53
    [HTTP_X_FORWARDED_FOR] => 119.164.27.53
    [REMOTE_ADDR] => 115.124.31.68
    .........
)

国产视频app在阿里CDN中,只有 [HTTP_ALI_CDN_REAL_IP] 與 [HTTP_X_FORWARDED_FOR]  包含了真實的IP地址。

七牛CDN打印結果:

Array
(
    [HTTP_ALI_CDN_REAL_IP] => 119.164.27.53
    [HTTP_X_FORWARDED_FOR] => 119.164.27.53
    [REMOTE_ADDR] => 182.92.246.161
    .........
)

国产视频app在七牛CDN下,打印的結果 [HTTP_ALI_CDN_REAL_IP]  和 [HTTP_X_FORWARDED_FOR]  中含有真實的IP地址

吐槽一下:七牛與阿里CDN在打印的結果,在某種程序上來說很是相似。

又拍云CDN打印結果:

Array
(
    [HTTP_X_FORWARDED_FOR] => 119.164.27.53
    [HTTP_X_REAL_IP] => 119.164.27.53
    [REMOTE_ADDR] => 150.138.216.79
    .........
)

在又拍云CDN下,打印結果,[HTTP_X_FORWARDED_FOR]  與  [HTTP_X_REAL_IP]  含有真實的IP地址。

未使用CDN關于IP字段

Array
(
    [REMOTE_ADDR] => 119.164.27.53
)

在未使用CDN的情況下,只有 “[REMOTE_ADDR]”包含了真實的IP地址,以上幾家列出的 [HTTP_X_FORWARDED_FOR]  與  [HTTP_X_REAL_IP] 并未出現。

幾家CDN打印結果分析:

国产视频app通過對比使用以上幾家CDN網站中,php文件打印結果,我們可以總結出以下三點:

1、在使用CDN時,$_SERVER變量中就會含有“HTTP_X_FORWARDED_FOR”元素,并且它里面含有用戶的真實IP地址,

2、未使用CDN時,$_SERVER變量中不會出現“HTTP_X_FORWARDED_FOR”元素

3、百度CDN下,“HTTP_X_FORWARDED_FOR”元素中是多個IP地址,并用英文逗號分開,第一個為用戶的真實IP地址。

PHP獲取網站使用CDN加速下用戶真實的IP地址代碼

我們可以通過判斷$_SERVER數組變量中是否含有“HTTP_X_FORWARDED_FOR”元素來判斷,網站是否使用CDN加速,如果使用了CDN加速并反回用戶的真實IP,如果沒實用就返回 “REMOTE_ADDR" 元素的值

代碼:

<?php
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
    //為了兼容百度的CDN,所以轉成數組
    $arr = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);
    echo $arr[0];
}else{
    echo $_SERVER['REMOTE_ADDR'];
}
?>

函數代碼:

如果你想在PHP的文件中多次調用以上代碼,我們把可以把它封裝成一個函數,如下

<?php
function GetUserIP(){
    if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
        //為了兼容百度的CDN,所以轉成數組
        $arr = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);
        return $arr[0];
    }else{
        return $_SERVER['REMOTE_ADDR'];
    }
}
?>

函數調用方法:

echo GetUserIP();