首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 獲取客戶端真實 IP 地址的完整解決方案

     編輯:PHP 綜合知識

在 Web 開發中,準確獲取用戶的真實 IP 地址是一項基礎且關鍵的需求。由於代理服務器、負載均衡器、CDN 等網絡設備的廣泛使用,單純依賴 $_SERVER['REMOTE_ADDR'] 往往無法獲得客戶端的真實 IP。本文將深入解析 PHP 判斷訪問 IP 的核心邏輯,並提供一個健壯、可復用的函數實現。

核心原理:HTTP 頭部的優先級判斷

當請求經過代理層時,原始客戶端 IP 通常會被附加在特定的 HTTP 頭部中。獲取真實 IP 的標準邏輯是按優先級檢查以下變量:

  1. HTTP_CLIENT_IP:部分代理服務器使用此頭部傳遞原始 IP,優先級最高。
  2. HTTP_X_FORWARDED_FOR:最常見的標準代理頭部,格式為 client, proxy1, proxy2,取第一個非未知 IP 即為真實客戶端 IP。
  3. REMOTE_ADDR:PHP 直接獲取的 TCP 連接來源 IP,若無代理則為真實 IP,否則為代理服務器 IP。

代碼實現:get_client_ip() 函數

以下函數封裝了上述邏輯,並增加了正則驗證確保返回格式合法的 IPv4 地址:

<?php
/**
 * 獲取客戶端真實 IP 地址
 * @return string 真實 IP 或 'unknown'
 */
function get_client_ip() {
    $ip = 'unknown';
    
    // 1. 檢查 HTTP_CLIENT_IP
    if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    }
    // 2. 檢查 HTTP_X_FORWARDED_FOR (可能包含多個 IP,取第一個有效值)
    elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        foreach ($ips as $single_ip) {
            $single_ip = trim($single_ip);
            if (filter_var($single_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
                $ip = $single_ip;
                break;
            }
        }
        // 如果沒找到公網 IP,退而求其次取第一個
        if ($ip === 'unknown') {
            $ip = trim($ips[0]);
        }
    }
    // 3. 最後 fallback 到 REMOTE_ADDR
    elseif (!empty($_SERVER['REMOTE_ADDR'])) {
        $ip = $_SERVER['REMOTE_ADDR'];
    }

    // 正則驗證 IPv4 格式 (簡易版,生產環境建議用 filter_var)
    if (!preg_match('/^[\d\.]{7,15}$/', $ip)) {
        return 'unknown';
    }
    
    return $ip;
}
?>

進階防偽建議

上述代碼適用於大多數場景,但在高安全性需求(如風控、支付)下,需注意:

  • 頭部可偽造:X-Forwarded-For 等頭部由客戶端發送,惡意用戶可偽造。務必配合 Web 服務器(Nginx/Apache)在入口層清洗或重寫這些頭部,只信任來自已知代理 IP 的轉發頭。
  • IPv6 支持:現代應用應擴展正則或使用 filter_var($ip, FILTER_VALIDATE_IP) 同時兼容 IPv6。
  • 雲環境:若使用 AWS ALB、Cloudflare 等服務,請參考其文檔獲取專用頭部(如 CF-Connecting-IP、X-Forwarded-For 的特定處理邏輯)。

總結

獲取真實 IP 的本質是「信任鏈」的建立。通過規範的代理配置與分層驗證代碼,可有效解決 90% 以上的場景需求。希望本文提供的函數能為你的 PHP 專案帶來便利。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved