It may seem simple at first because most of us should be relying on the server side environmental variable REMOTE_ADDR solely for client IP addresses:
echo $_SERVER['REMOTE_ADDR'];
Yet it’s barely enough to get the real IP for a variety of circumstances such as when the user is visiting your website from a proxy server. To everyone’s surprise, there are a lot more environmental variables regarding client IP address than just the most straightforward one, REMOTE_ADDR. Consider this snippet in the attempt to detect the real source IP address of the request:
function get_ip_address() {
foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key) {
if (array_key_exists($key, $_SERVER) === true) {
foreach (explode(',', $_SERVER[$key]) as $ip) {
if (filter_var($ip, FILTER_VALIDATE_IP) !== false) {
return $ip;
}
}
}
}
}
It first searches through a series of possible environmental variables that may contain the client IP address and uses whichever that is set and then extract the potential IP value to be validated. After successful validation by the PHP5 filter_var() function, the value is returned. You better not change the order these variable names are placed in the literal array.
This approach is much more sophisticated than just looking at REMOTE_ADDR but it’s far from mess-proof because it relies on the HTTP header information which can be easily manipulated anywhere along the way the request is routed to your server / website.
You should also read:
- PHP: How to distinguish values in $_POST or $_GET that are sent via HTTP requests and those that are set / assigned in the code
- Apache, PHP: Get Client Browser HTTP Request Headers Information
- PHP and JavaScript Variable / Value Transfer / Exchange: How to pass variable values from PHP to JavaScript or JavaScript to PHP?
- Use PHP to handle all incoming URL requests in a SEO friendly manner
- PHP: Check or Validate URL and Email Addresses – an Easier Way than Regular Expressions, the filter_var() Function


Facebook
Twitter
Google Plus
{ 11 comments… read them below or add one }
I got you stuff, really looks nice and tactical. But I tried to call the function this way:
echo get_ip_address(); but generated this error: Fatal error: Call to undefined function filter_var() in C:\wamp\www\php-bank\create-directory\index.php on line 10, That is the error that it generated, please help! I would love to get the reply in my mail box please! Thanks.
You may want to upgrade to the latest PHP version. :) filter_var() is a recent addition to the native functions.
$client_addr = filter_var((!empty($_SERVER['HTTP_CLIENT_IP']))? $_SERVER['HTTP_CLIENT_IP']:
(!empty($_SERVER['HTTP_X_FORWARDED_FOR']))? $_SERVER['HTTP_X_FORWARDED_FOR']:
(!empty($_SERVER['REMOTE_ADDR']))? $_SERVER['REMOTE_ADDR']:’UNKNOWN’, FILTER_SANITIZE_STRING);
This is not preferable because it jeopardizes the readability of the code.
Human efficiency comes way higher priority than that of machines or storage.
Thanks for script, I’ll try, it seems very useful.
This is the most elegant code I’ve seen for the job.
Nice work!
Very nice snippet, thanks a lot!
Hello, nice job here! I totally agree with Yang Yang on readability being the most important thing. Actually, for the sake of it, 2 extra things I’d do on your function are:
- use a regex and avoid one extra level of indentation (on the filter_var line)
- declare the array before the foreach (might have some speed benefits also, if an array is otherwise build at every cycle iteration – not sure on this; main point is nevertheless to be able to break long constant line in multiple ones, though, so o improve readability);
But hey, again, cool solution of yours ;-)
thanks! that works great
ip-spoofing get’s realy easy with this, just adding an extra header in enough.
[ $client_addr = filter_var((!empty($_SERVER['HTTP_CLIENT_IP']))? $_SERVER['HTTP_CLIENT_IP']:
(!empty($_SERVER['HTTP_X_FORWARDED_FOR']))? $_SERVER['HTTP_X_FORWARDED_FOR']:
(!empty($_SERVER['REMOTE_ADDR']))? $_SERVER['REMOTE_ADDR']:’UNKNOWN’, FILTER_SANITIZE_STRING) ]
{ 1 trackback }