因為工作上很多網站是放置於 CloudFlare
加上如果有使用 Load Balancer 做反向代理的話
在抓取用戶 IP 若是直接使用 PHP 的 remote_addr 是不太準確的
因此提供以下我所使用的抓取用戶 IP 函式,我一直以來都使用這個函式來作業,目前沒有遇過問題
function getIP() { if (validip(@$_SERVER["HTTP_CF_CONNECTING_IP"])) { return $_SERVER["HTTP_CF_CONNECTING_IP"]; } else if (validip(@$_SERVER["HTTP_CLIENT_IP"])) { return $_SERVER["HTTP_CLIENT_IP"]; } else if (validip(@$_SERVER["HTTP_X_FORWARDED"])) { return $_SERVER["HTTP_X_FORWARDED"]; } else if (validip(@$_SERVER["HTTP_FORWARDED_FOR"])) { return $_SERVER["HTTP_FORWARDED_FOR"]; } else if (validip(@$_SERVER["HTTP_FORWARDED"])) { return $_SERVER["HTTP_FORWARDED"]; } else { foreach(explode(",",@$_SERVER["HTTP_X_FORWARDED_FOR"]) as $ip) { if (validip(trim($ip))) {return $ip;} } return $_SERVER["REMOTE_ADDR"]; } } function validip($ip) { if (!empty($ip) && ip2long($ip)!=-1) { $reserved_ips = array ( array('10.0.0.0','10.255.255.255'), array('127.0.0.0','127.255.255.255'), array('169.254.0.0','169.254.255.255'), array('172.16.0.0','172.31.255.255'), array('192.168.0.0','192.168.255.255'), ); foreach ($reserved_ips as $r) { $min = ip2long($r[0]); $max = ip2long($r[1]); if ((ip2long($ip) >= $min) && (ip2long($ip) <= $max)) return false; } return true; } else { return false; } }
這篇文章也寫的相當不錯