LMSouq
php-dev Open

What is the most accurate way to retrieve a user's correct IP address in PHP?

CO
Corey Ballou
1 month ago
3 views
Problem Description
I know there are a plethora of **$_SERVER** variables headers available for IP address retrieval. I was wondering if there is a general consensus as to how to most accurately retrieve a user's real IP address (well knowing no method is perfect) using said variables? I spent some time trying to find an in depth solution and came up with the following code based on a number of sources. I would love it if somebody could please poke holes in the answer or shed some light on something perhaps more accurate. ***edit includes optimizations from @Alix*** /** * Retrieves the best guess of the client's actual IP address. * Takes into account numerous HTTP proxy headers due to variations * in how different ISPs handle IP addresses in headers between hops. */ public function get_ip_address() { // Check for shared internet/ISP IP if (!empty($_SERVER['HTTP_CLIENT_IP']) && $this->validate_ip($_SERVER['HTTP_CLIENT_IP'])) return $_SERVER['HTTP_CLIENT_IP']; // Check for IPs passing through proxies if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { // Check if multiple IP addresses exist in var $iplist = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); foreach ($iplist as $ip) { if ($this->validate_ip($ip)) return $ip; } } } if (!empty($_SERVER['HTTP_X_FORWARDED']) && $this->validate_ip($_SERVER['HTTP_X_FORWARDED'])) return $_SERVER['HTTP_X_FORWARDED']; if (!empty($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']) && $this->validate_ip($_SERVER['HTTP_X_CLUSTER_CLIENT_IP'])) return $_SERVER['HTTP_X_CLUSTER_CLIENT_IP']; if (!empty($_SERVER['HTTP_FORWARDED_FOR']) && $this->validate_ip($_SERVER['HTTP_FORWARDED_FOR'])) return $_SERVER['HTTP_FORWARDED_FOR']; if (!empty($_SERVER['HTTP_FORWARDED']) && $this->validate_ip($_SERVER['HTTP_FORWARDED'])) return $_SERVER['HTTP_FORWARDED']; // Return unreliable IP address since all else failed return $_SERVER['REMOTE_ADDR']; } /** * Ensures an IP address is both a valid IP address and does not fall within * a private network range. * * @access public * @param string $ip */ public function validate_ip($ip) { if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false) return false; self::$ip = $ip; return true; } Words of Warning (update) ---------------- `REMOTE_ADDR` still r...

AI-Generated Solution

Powered by LMSouq AI · GPT-4.1-mini

✓ Solution Ready
Analyzing problem and generating solution…
Was this solution helpful?
Back to Knowledge Base