Getting real IP address in PHP

Are you using $_SERVER[‘REMOTE_ADDR’] to find the the client’s IP address in PHP? Well dude, you might be amazed to know that it may not return the true IP address of the client at all time. If your client is connected to the Internet through Proxy Server then $_SERVER[‘REMOTE_ADDR’] in PHP just returns the the IP address of the proxy server not of the client’s machine. So here is a simple function in PHP to find the real IP address of the client’s machine. There are extra Server variable which might be available to determine the exact IP address of the client’s machine in PHP, they are HTTP_CLIENT_IP and HTTP_X_FORWARDED_FOR.

Function to find real IP address in PHP

function getRealIpAddr()
{
    if (!empty($_SERVER['HTTP_CLIENT_IP']))   //check ip from share internet
    {
      $ip=$_SERVER['HTTP_CLIENT_IP'];
    }
    elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))   //to check ip is pass from proxy
    {
      $ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
    }
    else
    {
      $ip=$_SERVER['REMOTE_ADDR'];
    }
    return $ip;
}

In this PHP function, first attempt is to get the direct IP address of client’s machine, if not available then try for forwarded for IP address using HTTP_X_FORWARDED_FOR. And if this is also not available, then finally get the IP address using REMOTE_ADDR.

79 thoughts on “Getting real IP address in PHP

  1. Mancub

    1) You forgot to return $ip
    2) The problem with “HTTP_” headers is that they can easily be faked by the client. I could make your function belive I have any address, simply by sending it an X-Forwarded-For header. Here’s a little proof of concept (what you see is a script that echoes the return value of your function):

    ovidiu@ovidiu-desktop:~$ telnet localhost 80
    Trying 127.0.0.1…
    Connected to localhost.
    Escape character is ‘^]’.
    GET /delme/ HTTP/1.0

    HTTP/1.1 200 OK
    Date: Tue, 01 Jan 2008 14:54:49 GMT
    Server: Apache/2.2.4 (Ubuntu) PHP/5.2.3-1ubuntu6.2
    X-Powered-By: PHP/5.2.3-1ubuntu6.2
    Content-Length: 10
    Connection: close
    Content-Type: text/html

    127.0.0.1
    Connection closed by foreign host.
    ovidiu@ovidiu-desktop:~$ telnet localhost 80
    Trying 127.0.0.1…
    Connected to localhost.
    Escape character is ‘^]’.
    GET /delme/ HTTP/1.0
    X-Forwarded-For: 10.0.0.1

    HTTP/1.1 200 OK
    Date: Tue, 01 Jan 2008 14:55:27 GMT
    Server: Apache/2.2.4 (Ubuntu) PHP/5.2.3-1ubuntu6.2
    X-Powered-By: PHP/5.2.3-1ubuntu6.2
    Content-Length: 9
    Connection: close
    Content-Type: text/html

    10.0.0.1
    Connection closed by foreign host.
    ovidiu@ovidiu-desktop:~$

    Of course, in real life you wouldn’t use telnet. That was just a demonstration. You would send that header using cURL or fsockopen(). You could generate IP addresses randomly and fool the script every time.

  2. Roshan

    Thanks for figuring out the missing return statement, i’ve placed it in the code now.

    And you’re right about “HTTP_” headers, they can easily be faked.

    And, if you really want to fake the IP address then you can easily do it by browing the web anynomously with fake proxy server. You can find lots of such websites which allows you to browse the web anynomously.

  3. Andrew

    Although we are trusting the user not to spoof the HTTP headers, there is another flaw depending on what you want from this function. Very often you’ll just get a 192.168.*.* or 10.*.*.* address, telling you just the private address the client got from their DHCP server.

    I’ve written a Perl module that uses NetAddr::IP to determine if an IP address is private or public. I then check each of HTTP_CLIENT_IP, HTTP_X_FORWARDED_FOR and REMOTE_ADDR and return the first one that is public. If none of them are public I return REMOTE_ADDR.

  4. Hi there…Thanks for the nice read, keep up the interesting posts..what a nice Friday

  5. Vipul

    So, dear Php Gurus, what’s the final code? Please let me know.

  6. Hey!…Thanks for the nice read, keep up the interesting posts..what a nice Saturday

  7. There are much more headers that you can check if someone is using proxy. Thes is what I know:
    HTTP_PRAGMA, HTTP_XONNECTION, HTTP_CACHE_INFO, HTTP_XPROXY, HTTP_PROXY, HTTP_PROXY_CONNECTION, HTTP_CLIENT_IP, HTTP_VIA, HTTP_X_COMING_FROM, HTTP_X_FORWARDED_FOR, HTTP_X_FORWARDED, HTTP_COMING_FROM, HTTP_FORWARDED_FOR, HTTP_FORWARDED, ZHTTP_CACHE_CONTROL

  8. Kim Smith

    Hi there…Man i love reading your blog, interesting posts ! it was a great Saturday

  9. Hello…I Googled for benji smith, but found your page about …and have to say thanks. nice read.

  10. I love magic!

    function getIpAddress() {
    return (empty($_SERVER[‘HTTP_CLIENT_IP’])?(empty($_SERVER[‘HTTP_X_FORWARDED_FOR’])?
    $_SERVER[‘REMOTE_ADDR’]:$_SERVER[‘HTTP_X_FORWARDED_FOR’]):$_SERVER[‘HTTP_CLIENT_IP’]);
    }

  11. sha

    How to get the username and computer name using PHP..? Thanks In advance

  12. if the user is using WAN then you can use gethostbyaddr($_SERVER[‘REMOTE_ADDR’]); to get the hostname , in LAN it’s not possible.

  13. It is possible to find said information on a LAN, it just has to be a LAN with reverse DNS for all machines in the DNS servers. This should also be possible with zeroconf (also under many other names) networking, but I don’t believe PHP functions exist for this yet.

  14. This function does not track Proxy servers. e.g I tested it using anonymous browsing site e.g hidemyass.com and the site bypassed this function by sending fake ip to me.

  15. Haroon…it’s true that this function can’t help from anonymous browsing man…

  16. jayu

    Hi Roshan,

    Thanks for your post. Its nice and useful.

    Thanks
    Jayu shah

  17. Ed

    This is a very interesting article. I do agree with what one user posted about DHCP. IP addresses such as 192.168 are for wireless network routers, and users on laptops like me can set their own IP address. This is NOT the IP address you want to collect when trying to get the users real IP address.

    In the end, I believe this function isn’t any more reliable that REMOTE_ADDR. It only shows hackers, spammers, and/or other malicious people how to block their IP address! If you want to go hardcore on getting their IP, I would suggest collecting all their possible IP addresses, including the HTTP_ and the REMOTE_ADDR. This script does not guarantee in any way that the IP address is right.
    Note besides using $_SERVER, this is also getenv.
    ex.
    $ip = getenv(‘REMOTE_ADDR’);

    If you really want to look more into this post, go to the page on PHP.net for the getenv function, there are numerous post very similar to this containing more complex functions to collect user’s IP address, I think mkaman has the best post, go to the page:
    http://us3.php.net/getenv

  18. hi,
    how can i determine the country of the ip after i get the ip??
    thank’s

  19. @miaki…I’ll write a post about the soon..

  20. Thank alot! it helped me more bout IP in PHP

    thanks again! your code is usefull!

  21. lolas

    this code is very useful – thanks

  22. Thank alot!

  23. Mamoon Rahid

    Thanks for useful information

  24. But how do you get the IP of someone behind a proxy?

  25. @ip address finding – There is no way to find the IP address behind the anonymous proxy

  26. Very nice and simple method to return the IP address of a visitor to your site (most of the time).

    You can’t prevent the spoofing, it’s something you have to live with.

  27. Vikas

    For me,it did not give up my ip address.It just displays the loop back address.my ip inside LAN is 192.168.1.107.This is my internal IP.your script is just showing up the loop back address i.e., 127.0.0.1

  28. A QUESTION FROM AN IDIOT

    is there a way in php of knowing if the email address supplied by the user is existing?

    thanks…

    -A QUESTION FROM AN IDIOT

  29. function getIpAddress() {
    return (empty($_SERVER[‘HTTP_CLIENT_IP’])?(empty($_SERVER[‘HTTP_X_FORWARDED_FOR’])?
    $_SERVER[‘REMOTE_ADDR’]:$_SERVER[‘HTTP_X_FORWARDED_FOR’]):$_SERVER[‘HTTP_CLIENT_IP’]);
    }

    isn’t useless because some proxy can cheat it, maybe java script is powerfull to handle this…

  30. @ducan – there is no way you can get rid of anonymous proxy..

  31. I have go through this post and found very helpful but i still could not able to found the real ip. I use geoip api to track the country but when i get the ip from given function it could not return country and if i try http://www.whatismyip.com ip address it return the country correctly.
    thanks,
    akram.

  32. feona

    i use http://www.tracemyip.com so far it has given me the correct ip

  33. Thanks so much for this code! It has been invaluable in creating a localization solution for our site.

  34. So can I just copy and paste this PHP script onto another server, and then poll this script to return my own IP ?

  35. Ben

    This doesn’t work no matter what you do! I am behind a router and this script will give the router ip, but not mine!

  36. tarang

    hi
    couple of months ago u upload a ip locator code using which using user can easily implement that code in his website.i download the same.i just want to know y there is need to create the mysql database i.e “Visitormap” as we are using the database online.

  37. Ricky

    thanks tux86…………ur code works for me…..

  38. if we want to find the proper location using IP the how is it possible

  39. fahad mahmood

    thnx everybody, it will help me to filter my visits statistics more

  40. Ben

    None of anything listed here will give you the true user IP address if a user here thinks they have gotten it then the have no clue that they are talking about. This will give the public IP, but unless it is static then you cannot use it for any software security or anything else.

  41. Thank you! Excellent post. I look forward to its use and implementation in my website.

  42. superb script

  43. Advert

    This could be a (potential) security exploit.
    Fake it like mentioned, but instead of using an IP address, fill it with junk.

  44. Brandon

    hi, just wanna say thx for sharing the code.

  45. $_SERVER header almost always empty?

    http://www.thuiss.nl/iptest.php

  46. i used this function and its working . Thank you.

  47. Here are different ways to store an IP or an IP range as well as query for the IPs.
    http://strictcoder.blogspot.com/2009/08/different-ways-to-query-for-ip-in-your.html

  48. Thanks for the help with code that I searched and interesting subject discussion.

  49. The final code is

  50. As Andrew wrote on 3 January, 2008,
    I’ve written a Perl module that uses NetAddr::IP to determine if an IP address is private or public. I then check each of HTTP_CLIENT_IP, HTTP_X_FORWARDED_FOR and REMOTE_ADDR and return the first one that is public. If none of them are public I return REMOTE_ADDR.
    Any option to have this code shared ?

Comments are closed.