232

I want to get the client IP address who uses my website. I am using the PHP $_SERVER superglobal:

$_SERVER['REMOTE_ADDR'];

But I see it can not give the correct IP address using this. I get my IP address and see it is different from my IP address and I can also see my IP address in some website like:

http://whatismyipaddress.com/

I paste the IP address which give my PHP function but this website shows no result about this. How does this problem come about and how can I get IP address of the client?

Charles
  • 50,943
  • 13
  • 104
  • 142
user1752627
  • 2,527
  • 2
  • 15
  • 10
  • 5
    http://stackoverflow.com/questions/1634782/what-is-the-most-accurate-way-to-retrieve-a-users-correct-ip-address-in-php?rq=1 – Ares Mar 29 '13 at 07:26
  • 2
    If you are on a local server it will be different (eg: 192.168.xxx.xxx), because you check from whatsmyip you are getting your isp ip they supplied to you. – Class Mar 29 '13 at 07:27
  • On your computer you'll see your private IP (192..) and on websites you'll your public IP (84...). In general your public IP is the only interesting one. – CustomX Aug 02 '13 at 09:25
  • 12
    Again, not really a duplicate, seeing as how this is the best ranked by Google. Stackoverflow guys, come on. "Marked as Duplicate" happens too often. If this ranks better, it's for good reason. Google has spoken. – 3Dom Jan 22 '15 at 12:02

4 Answers4

426

The simplest way to get the visitor’s/client’s IP address is using the $_SERVER['REMOTE_ADDR'] or $_SERVER['REMOTE_HOST'] variables.

However, sometimes this does not return the correct IP address of the visitor, so we can use some other server variables to get the IP address.

The below both functions are equivalent with the difference only in how and from where the values are retrieved.

getenv() is used to get the value of an environment variable in PHP.

// Function to get the client IP address
function get_client_ip() {
    $ipaddress = '';
    if (getenv('HTTP_CLIENT_IP'))
        $ipaddress = getenv('HTTP_CLIENT_IP');
    else if(getenv('HTTP_X_FORWARDED_FOR'))
        $ipaddress = getenv('HTTP_X_FORWARDED_FOR');
    else if(getenv('HTTP_X_FORWARDED'))
        $ipaddress = getenv('HTTP_X_FORWARDED');
    else if(getenv('HTTP_FORWARDED_FOR'))
        $ipaddress = getenv('HTTP_FORWARDED_FOR');
    else if(getenv('HTTP_FORWARDED'))
       $ipaddress = getenv('HTTP_FORWARDED');
    else if(getenv('REMOTE_ADDR'))
        $ipaddress = getenv('REMOTE_ADDR');
    else
        $ipaddress = 'UNKNOWN';
    return $ipaddress;
}

$_SERVER is an array that contains server variables created by the web server.

// Function to get the client IP address
function get_client_ip() {
    $ipaddress = '';
    if (isset($_SERVER['HTTP_CLIENT_IP']))
        $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
    else if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
        $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
    else if(isset($_SERVER['HTTP_X_FORWARDED']))
        $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
    else if(isset($_SERVER['HTTP_FORWARDED_FOR']))
        $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
    else if(isset($_SERVER['HTTP_FORWARDED']))
        $ipaddress = $_SERVER['HTTP_FORWARDED'];
    else if(isset($_SERVER['REMOTE_ADDR']))
        $ipaddress = $_SERVER['REMOTE_ADDR'];
    else
        $ipaddress = 'UNKNOWN';
    return $ipaddress;
}
Cheok Yan Cheng
  • 47,586
  • 132
  • 466
  • 875
Shiv
  • 4,332
  • 1
  • 13
  • 3
  • 44
    note that this function can also lead you very wrong. in particular, HTTP_X_FORWARDED_FOR can be anything a client chooses to set, whereas REMOTE_ADDR is considerably harder to fake, if client wants to get the actual response. – eis Aug 02 '13 at 09:23
  • 3
    also, even if it is not faked, there are lots of setups where it will just be populated with clients internal network ip, which would be useless. – eis Aug 02 '13 at 09:24
  • 5
    this code is vulnerable to spoofing be careful where you use it! – jnhghy - Alexandru Jantea Jan 19 '15 at 14:11
  • 5
    You need to read this **before** you get hacked:http://stackoverflow.com/questions/3003145/how-to-get-the-client-ip-address-in-php#comment50230065_3003233 – Pacerier Jun 29 '15 at 04:31
  • why it always returns::1? – huykon225 Jul 22 '17 at 02:57
  • 2
    @huykon225 Because You Are in Localhost. Try by uploading script on server. – TarangP Jan 11 '18 at 05:50
  • else ifs should be elseifs – Andrew Apr 02 '18 at 14:26
  • @eis how you solved this. It's showing me wrong ip. My ip belongs to ipv6 but it shows some wrong ipv4. how to solve this ? – Aditya Srivastava May 21 '18 at 05:58
  • @AdityaSrivastava I don't think there is a bulletproof way to solve this. – eis May 21 '18 at 14:54
  • @AdityaSrivastava I don't think there is a bulletproof way to solve this. Use `$_SERVER['REMOTE_ADDR']`, and if that doesn't work, some case-specific hack might. Or might not. – eis May 21 '18 at 18:23
  • How would we get this to display the IP on the screen? – Voldemort's Wrath May 27 '19 at 17:12
  • @Cheok Yan Cheng: As you changed the actual code (use of `isset`), you ought to explain why. – Peter Mortensen Aug 09 '19 at 13:59
  • is the value of the environment set automatically by PHP? – Fauzan Edris Jun 18 '21 at 09:53
  • From a programming perspective, if you think `HTTP_X_FORWARDED_FOR` is vulnerable, then make it the `last if statement block` and put `REMOTE_ADDR` as `the first if statement block` because it is harder to fake it. Problem solved :--) – ToiletGuy Sep 09 '22 at 20:07
143

In PHP 5.3 or greater, you can get it like this:

$ip = getenv('HTTP_CLIENT_IP')?:
getenv('HTTP_X_FORWARDED_FOR')?:
getenv('HTTP_X_FORWARDED')?:
getenv('HTTP_FORWARDED_FOR')?:
getenv('HTTP_FORWARDED')?:
getenv('REMOTE_ADDR');
Michael
  • 9,223
  • 3
  • 25
  • 23
1
    $ipaddress = '';
    if ($_SERVER['HTTP_CLIENT_IP'] != '127.0.0.1')
        $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
    else if ($_SERVER['HTTP_X_FORWARDED_FOR'] != '127.0.0.1')
        $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
    else if ($_SERVER['HTTP_X_FORWARDED'] != '127.0.0.1')
        $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
    else if ($_SERVER['HTTP_FORWARDED_FOR'] != '127.0.0.1')
        $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
    else if ($_SERVER['HTTP_FORWARDED'] != '127.0.0.1')
        $ipaddress = $_SERVER['HTTP_FORWARDED'];
    else if ($_SERVER['REMOTE_ADDR'] != '127.0.0.1')
        $ipaddress = $_SERVER['REMOTE_ADDR'];
    else
        $ipaddress = 'UNKNOWN';
Rene Berwanger
  • 157
  • 1
  • 2
-18

Here is a function to get the IP address using a filter for local and LAN IP addresses:

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 $IPaddress){
                $IPaddress = trim($IPaddress); // Just to be safe

                if (filter_var($IPaddress,
                               FILTER_VALIDATE_IP,
                               FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)
                    !== false) {

                    return $IPaddress;
                }
            }
        }
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
rohitarora
  • 1,380
  • 2
  • 13
  • 20
  • 39
    -1 for [not giving your sources](http://stackoverflow.com/a/2031935/238419)... – BlueRaja - Danny Pflughoeft Nov 22 '13 at 17:11
  • `code` function getLocalIP(){ exec("ipconfig /all", $output); foreach($output as $line){ if (preg_match("/(.*)IPv4 Address(.*)/", $line)){ $ip = $line; $ip = str_replace("IPv4 Address. . . . . . . . . . . :","",$ip); $ip = str_replace("(Preferred)","",$ip); } } return trim($ip); } – Prem Kumar Maurya Jul 27 '14 at 03:59
  • 4
    so many negative flags yet only this answer contains FILTER_VALIDATE_IP which can be a major security concern if not filtered. – saur Oct 18 '19 at 06:28