2013-07-05 40 views
1

我想存儲IP地址以及用戶註冊,發佈,上傳等我以前的網站我一直使用ip2long/long2ip並將其作爲UNSIGNED INT保存爲IPv4我唯一的擔憂。所以我會通過ip2long運行IP地址,存儲它,當我檢索它時,請使用long2ip。但是現在我想確保它有更多的未來證明,並解決IPv4和IPv6問題。PHP IPv4和IPv6功能存儲在數據庫中

這是一個功能,我想出迄今同時處理IPv4和IPv6:

function ipCheck() 
{ 
    // Get IP Address 
     if (!empty($_SERVER['HTTP_CLIENT_IP'])) // Shared client 
     { 
      $ipAddress = $_SERVER['HTTP_CLIENT_IP']; 
     } 
     else if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) // Proxy address 
     { 
      $ipAddress = $_SERVER['HTTP_X_FORWARDED_FOR']; 
     } 
     else 
     { 
      $ipAddress = $_SERVER['REMOTE_ADDR']; // User viewing 
     } 

    // Over IP for testing 
     /* 
      IP Examples for testing 

      IPv4: 64.233.160.0 
      IPv6: 2607:f0d0:1002:51::4 
      IPv6: 2607:f0d0:1002:0051:0000:0000:0000:0004 
     */ 

     $ipAddress = '2607:f0d0:1002:0051:0000:0000:0000:0004'; // Comment out this line for actual IP 

    // Validate IP 
     if (filter_var($ipAddress, FILTER_VALIDATE_IP)) 
     { 
      if (strpos($ipAddress, ':') !== false) 
      { 
       $ipType = 'IPv6'; 
       $ipAddressDB = inet_pton($ipAddress); 
      } 
      else 
      { 
       $ipType = 'IPv4'; 
       $ipAddressDB = ip2long($ipAddress); 
      } 
     } 
     else 
     { 
      $ipType = 'Invalid'; 
      $ipAddressDB = $ipAddress; 
     } 

    // Display results 
     echo '<strong>IP Type: </strong>'.$ipType.'<br />', 
      '<strong>IP Address: </strong>'.$ipAddress.'<br />', 
      '<strong>DatabaseIP: </strong>'.$ipAddressDB; 
} 

ipCheck(); 

我個人沒有IPv6地址,所以我已替換爲測試目的而$ipAddress變量。

一切工作正常的IPv4地址,但$ipAddressDB IPv6地址返回值&(diamond-with-question-mark)(diamond-with-question-mark)Q當我使用2607:f0d0:1002:0051:0000:0000:0000:0004測試IP,我真的不知道爲什麼?我使用inet_pton錯了嗎?我必須添加一些東西嗎?是否因爲測試IPv6地址?我想假設一旦我得到那個工作,因爲我們需要存儲在2列中,我爲數據庫IP創建了2個變量,如果它是IPv4,我將它分配給變量1,並將變量2留空。那麼如果它是IPv6,我將它分開,將前半部分放在變量1中,將第二半放入變量2中。然後,當插入/選擇時,如果第二列是空的,我們可以認爲它是IPv4地址?

我甚至不是100%確定我所要做的事實際上是可行的嗎?如果不是,那麼最好是直接拿走IPv6地址(沒有inet_pton),然後就這樣拆分它們?

+1

你需要什麼ip地址?您可以信任的唯一變量是$ _SERVER ['REMOTE_ADDR']'。其他人只是垃圾。 – zerkms

+0

我可以問爲什麼其他人是垃圾? (嚴重的問題) – Joe

+2

,因爲發件人可以從字面上放置任何東西(並且只有'REMOTE_ADDR'由網絡服務器從連接信息填充(也可以忘記,但發件人不會檢索迴應) – zerkms

回答

1

您正在以二進制形式查看地址。 「&」是UTF-8 0x26,0xf0和0xd0是無效的UTF-8(顯示爲「 」),「Q」是UTF-8 0x51,其他字節顯示爲空。在存儲之前將字符串編碼爲十六進制(然後您可以完全相同的方式處理IPv4地址)。

+0

像這樣? '$ ipAddressBin2Hex = bin2hex($ ipAddress); $ ipAddressDB = inet_pton($ ipAddressBin2Hex);'抱歉,如果我弄錯了! – Joe

+0

正如你所提到的編碼,它讓我想到了,這是否與我設置一個'meta'標籤'charset'屬性。我通常使用'',所以我通過設置並將該函數放在''內測試了它。然後創建一個新的頁面,除了我的'ipCheck()'函數外,其他頁面上的值都是不同的。我按照上面寫的方式嘗試了'bin2hex'函數,並且收到了'Warning:inet_pton()[function.inet-pton]:無法識別的地址... ... – Joe