227

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,010
  • 13
  • 100
  • 141
user1752627
  • 2,477
  • 2
  • 14
  • 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

5 Answers5

410

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
  • 48,324
  • 124
  • 436
  • 828
Shiv
  • 4,172
  • 1
  • 12
  • 3
141

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,153
  • 3
  • 23
  • 23
  • 2
    This worked for me where as the one marked as correct answer didn't. – Matical Feb 04 '14 at 09:25
  • Is `getenv` better than using `$_SERVER`? – Kallewallex Feb 06 '14 at 19:35
  • 9
    getenv returns a false if the variable isn't set, where $_SERVER will error with "undefined index" if the variable isn't set. – Michael Feb 07 '14 at 01:45
  • 4
    I usually don't like nested ternaries, but I really like it in this case... – Charles Harmon Jul 18 '14 at 20:49
  • They can get convoluted, but the alternative was nested if...which is truly ugly. Glad you like it. – Michael Jul 18 '14 at 22:20
  • 2
    I tend to avoid ternaries altogether in PHP cause of its (illogical) left-associativity. See http://phpsadness.com/sad/30 – GeriBoss Aug 03 '14 at 19:16
  • 3
    GeriBoss, it's not so hard to figure out a solution to that phpsadness test case and make the code more readable at the same time: echo (FALSE ? "a" : (FALSE ? "b" : "c"))."\n"; echo (FALSE ? "a" : (TRUE ? "b" : "c"))."\n"; echo (TRUE ? "a" : (FALSE ? "b" : "c"))."\n"; echo (TRUE ? "a" : (TRUE ? "b" : "c"))."\n"; – Michael Nov 20 '14 at 05:34
  • short and sweet answer!!.... – Kunal May 04 '17 at 14:09
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
  • 147
  • 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,030
  • 21
  • 100
  • 124
rohitarora
  • 1,374
  • 2
  • 13
  • 20
  • 37
    -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
  • 1
    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
-25

It also works fine for internal IP addresses:

 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;
 }
Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
  • 13
    100% copy of Sivanesh Govindan answer – JuZer Oct 19 '16 at 13:37
  • 1
    return ($ip=getenv('HTTP_CLIENT_IP' ))?$ip:( ($ip=getenv('HTTP_X_FORWARDED_FOR' ))?$ip:( ($ip=getenv('HTTP_X_FORWARDED' ))?$ip:( ($ip=getenv('HTTP_FORWARDED_FOR' ))?$ip:( ($ip=getenv('HTTP_FORWARDED' ))?$ip:( ($ip=getenv('REMOTE_ADDR' ))?$ip:false ))))); – AbdulRahman AlShamiri Aug 16 '18 at 23:22