最近在做系統日志功能,需要獲取登錄用戶ip,而系統是TP5已自帶獲取ip的函數$request->ip()。然后在興趣下一步步分析了一下該函數並加上了注釋
/** * 獲取客戶端IP地址 * @param integer $type 返回類型 0 返回IP地址 1 返回IPV4地址數字 * @param boolean $adv 是否進行高級模式獲取(有可能被偽裝) * @return mixed */ public function ip($type = 0, $adv = false) { $type = $type ? 1 : 0; //判斷是否傳入type=1參數,又則求ipv4地址數字 static $ip = null; //定義為靜態變量,防止重復調用 if (null !== $ip) { return $ip[$type]; } /* * 獲取客戶端ip有幾種方式,當用戶使用了代理服務器的時候,通過$_SERVER['HTTP_X_FORWARDED_FOR']或 * $_SERVER['HTTP_CLIENT_IP']獲取,當然獲取ip的方式不止包括這些,還有比如getenv('REMOTE_ADDR')等 * */ if ($adv) { //對用戶是否傳參數判斷通過什么方式獲取ip if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); //等到代理ip和用戶本機ip $pos = array_search('unknown', $arr); //對獲取的值進行過濾判斷 if (false !== $pos) { unset($arr[$pos]); } $ip = trim(current($arr)); } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; } elseif (isset($_SERVER['REMOTE_ADDR'])) { $ip = $_SERVER['REMOTE_ADDR']; } } elseif (isset($_SERVER['REMOTE_ADDR'])) { $ip = $_SERVER['REMOTE_ADDR']; } // IP地址合法驗證 $long = sprintf("%u", ip2long($ip)); $ip = $long ? [$ip, $long] : ['0.0.0.0', 0]; return $ip[$type]; }