How to get my ip address in php?

Whatever you do, make sure not to trust data sent from the client. $_SERVER['REMOTE_ADDR'] contains the real IP address of the connecting party. That is the most reliable value you can find.

However, they can be behind a proxy server in which case the proxy may have set the $_SERVER['HTTP_X_FORWARDED_FOR'], but this value is easily spoofed. For example, it can be set by someone without a proxy, or the IP can be an internal IP from the LAN behind the proxy.

This means that if you are going to save the $_SERVER['HTTP_X_FORWARDED_FOR'], make sure you also save the $_SERVER['REMOTE_ADDR'] value. E.g. by saving both values in different fields in your database.

If you are going to save the IP to a database as a string, make sure you have space for at least 45 characters. IPv6 is here to stay and those addresses are larger than the older IPv4 addresses.

[Note that IPv6 usually uses 39 characters at most but there is also a special IPv6 notation for IPv4 addresses which in its full form can be up to 45 characters. So if you know what you are doing you can use 39 characters, but if you just want to set and forget it, use 45].

answered Jun 9, 2010 at 5:15

Emil VikströmEmil Vikström

88.6k15 gold badges134 silver badges170 bronze badges

5

$_SERVER['REMOTE_ADDR'] may not actually contain real client IP addresses, as it will give you a proxy address for clients connected through a proxy, for example. That may well be what you really want, though, depending what your doing with the IPs. Someone's private RFC1918 address may not do you any good if you're say, trying to see where your traffic is originating from, or remembering what IP the user last connected from, where the public IP of the proxy or NAT gateway might be the more appropriate to store.

There are several HTTP headers like X-Forwarded-For which may or may not be set by various proxies. The problem is that those are merely HTTP headers which can be set by anyone. There's no guarantee about their content. $_SERVER['REMOTE_ADDR'] is the actual physical IP address that the web server received the connection from and that the response will be sent to. Anything else is just arbitrary and voluntary information. There's only one scenario in which you can trust this information: you are controlling the proxy that sets this header. Meaning only if you know 100% where and how the header was set should you heed it for anything of importance.

Having said that, here's some sample code:

if [!empty[$_SERVER['HTTP_CLIENT_IP']]] {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif [!empty[$_SERVER['HTTP_X_FORWARDED_FOR']]] {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
    $ip = $_SERVER['REMOTE_ADDR'];
}

Editor's note: Using the above code has security implications. The client can set all HTTP header information [ie. $_SERVER['HTTP_...] to any arbitrary value it wants. As such it's far more reliable to use $_SERVER['REMOTE_ADDR'], as this cannot be set by the user.

From: //roshanbh.com.np/2007/12/getting-real-ip-address-in-php.html

answered Sep 11, 2008 at 4:01

11

answered Jun 9, 2010 at 4:51

lemonlemon

9,0157 gold badges37 silver badges45 bronze badges

7

Here is a cleaner code sample of a good way to get the IP address of the user.

$ip = $_SERVER['HTTP_CLIENT_IP'] 
   ? $_SERVER['HTTP_CLIENT_IP'] 
   : [$_SERVER['HTTP_X_FORWARDED_FOR'] 
        ? $_SERVER['HTTP_X_FORWARDED_FOR'] 
        : $_SERVER['REMOTE_ADDR']];

Here is a shorter version that uses the elvis operator:

$_SERVER['HTTP_CLIENT_IP'] 
   ? : [$_SERVER['HTTP_X_FORWARDED_FOR'] 
   ? : $_SERVER['REMOTE_ADDR']];

Here is a version that uses isset to remove notices [thank you, @shasi kanth]:

$ip = isset[$_SERVER['HTTP_CLIENT_IP']] 
    ? $_SERVER['HTTP_CLIENT_IP'] 
    : [isset[$_SERVER['HTTP_X_FORWARDED_FOR']] 
      ? $_SERVER['HTTP_X_FORWARDED_FOR'] 
      : $_SERVER['REMOTE_ADDR']];

answered Oct 8, 2014 at 16:20

josh223a123josh223a123

1,9631 gold badge12 silver badges21 bronze badges

16

It should be contained in the $_SERVER['REMOTE_ADDR'] variable.

JJJ

32.5k20 gold badges88 silver badges102 bronze badges

answered Sep 11, 2008 at 3:38

Kyle CroninKyle Cronin

76.3k42 gold badges148 silver badges163 bronze badges

My favourite solution is the way Zend Framework 2 uses. It also considers the $_SERVER properties HTTP_X_FORWARDED_FOR, HTTP_CLIENT_IP, REMOTE_ADDR but it declares a class for it to set some trusted proxies and it returns one IP address not an array. I think this is the solution that comes closest to it:

class RemoteAddress
{
    /**
     * Whether to use proxy addresses or not.
     *
     * As default this setting is disabled - IP address is mostly needed to increase
     * security. HTTP_* are not reliable since can easily be spoofed. It can be enabled
     * just for more flexibility, but if user uses proxy to connect to trusted services
     * it's his/her own risk, only reliable field for IP address is $_SERVER['REMOTE_ADDR'].
     *
     * @var bool
     */
    protected $useProxy = false;

    /**
     * List of trusted proxy IP addresses
     *
     * @var array
     */
    protected $trustedProxies = array[];

    /**
     * HTTP header to introspect for proxies
     *
     * @var string
     */
    protected $proxyHeader = 'HTTP_X_FORWARDED_FOR';

    // [...]

    /**
     * Returns client IP address.
     *
     * @return string IP address.
     */
    public function getIpAddress[]
    {
        $ip = $this->getIpAddressFromProxy[];
        if [$ip] {
            return $ip;
        }

        // direct IP address
        if [isset[$_SERVER['REMOTE_ADDR']]] {
            return $_SERVER['REMOTE_ADDR'];
        }

        return '';
    }

    /**
     * Attempt to get the IP address for a proxied client
     *
     * @see //tools.ietf.org/html/draft-ietf-appsawg-http-forwarded-10#section-5.2
     * @return false|string
     */
    protected function getIpAddressFromProxy[]
    {
        if [!$this->useProxy
            || [isset[$_SERVER['REMOTE_ADDR']] && !in_array[$_SERVER['REMOTE_ADDR'], $this->trustedProxies]]
        ] {
            return false;
        }

        $header = $this->proxyHeader;
        if [!isset[$_SERVER[$header]] || empty[$_SERVER[$header]]] {
            return false;
        }

        // Extract IPs
        $ips = explode[',', $_SERVER[$header]];
        // trim, so we can compare against trusted proxies properly
        $ips = array_map['trim', $ips];
        // remove trusted proxy IPs
        $ips = array_diff[$ips, $this->trustedProxies];

        // Any left?
        if [empty[$ips]] {
            return false;
        }

        // Since we've removed any known, trusted proxy servers, the right-most
        // address represents the first IP we do not know about -- i.e., we do
        // not know if it is a proxy server, or a client. As such, we treat it
        // as the originating IP.
        // @see //en.wikipedia.org/wiki/X-Forwarded-For
        $ip = array_pop[$ips];
        return $ip;
    }

    // [...]
}

See the full code here: //raw.githubusercontent.com/zendframework/zend-http/master/src/PhpEnvironment/RemoteAddress.php

answered Jul 7, 2014 at 9:02

algorhythmalgorhythm

8,2822 gold badges34 silver badges46 bronze badges

4

There are different types of users behind the Internet, so we want to catch the IP address from different portions. Those are:

1. $_SERVER['REMOTE_ADDR'] - This contains the real IP address of the client. That is the most reliable value you can find from the user.

2. $_SERVER['REMOTE_HOST'] - This will fetch the host name from which the user is viewing the current page. But for this script to work, hostname lookups on inside httpd.conf must be configured.

3. $_SERVER['HTTP_CLIENT_IP'] - This will fetch the IP address when the user is from shared Internet services.

4. $_SERVER['HTTP_X_FORWARDED_FOR'] - This will fetch the IP address from the user when he/she is behind the proxy.

So we can use this following combined function to get the real IP address from users who are viewing in diffrent positions,

// Function to get the user IP address
function getUserIP[] {
    $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_X_CLUSTER_CLIENT_IP']]]
        $ipaddress = $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
    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;
}

answered Dec 29, 2016 at 15:18

K.SuthagarK.Suthagar

2,1481 gold badge15 silver badges28 bronze badges

1

The following is the most advanced method I have found, and I have already tried some others in the past. It is valid to ensure to get the IP address of a visitor [but please note that any hacker could falsify the IP address easily].

function get_ip_address[] {

    // Check for shared Internet/ISP IP
    if [!empty[$_SERVER['HTTP_CLIENT_IP']] && validate_ip[$_SERVER['HTTP_CLIENT_IP']]] {
        return $_SERVER['HTTP_CLIENT_IP'];
    }

    // Check for IP addresses passing through proxies
    if [!empty[$_SERVER['HTTP_X_FORWARDED_FOR']]] {

        // Check if multiple IP addresses exist in var
        if [strpos[$_SERVER['HTTP_X_FORWARDED_FOR'], ','] !== false] {
            $iplist = explode[',', $_SERVER['HTTP_X_FORWARDED_FOR']];
            foreach [$iplist as $ip] {
                if [validate_ip[$ip]]
                    return $ip;
            }
        }
        else {
            if [validate_ip[$_SERVER['HTTP_X_FORWARDED_FOR']]]
                return $_SERVER['HTTP_X_FORWARDED_FOR'];
        }
    }
    if [!empty[$_SERVER['HTTP_X_FORWARDED']] && validate_ip[$_SERVER['HTTP_X_FORWARDED']]]
        return $_SERVER['HTTP_X_FORWARDED'];
    if [!empty[$_SERVER['HTTP_X_CLUSTER_CLIENT_IP']] && validate_ip[$_SERVER['HTTP_X_CLUSTER_CLIENT_IP']]]
        return $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
    if [!empty[$_SERVER['HTTP_FORWARDED_FOR']] && validate_ip[$_SERVER['HTTP_FORWARDED_FOR']]]
        return $_SERVER['HTTP_FORWARDED_FOR'];
    if [!empty[$_SERVER['HTTP_FORWARDED']] && 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.
 */
function validate_ip[$ip] {

    if [strtolower[$ip] === 'unknown']
        return false;

    // Generate IPv4 network address
    $ip = ip2long[$ip];

    // If the IP address is set and not equivalent to 255.255.255.255
    if [$ip !== false && $ip !== -1] {
        // Make sure to get unsigned long representation of IP address
        // due to discrepancies between 32 and 64 bit OSes and
        // signed numbers [ints default to signed in PHP]
        $ip = sprintf['%u', $ip];

        // Do private network range checking
        if [$ip >= 0 && $ip = 167772160 && $ip = 2130706432 && $ip = 2851995648 && $ip = 2886729728 && $ip = 3221225984 && $ip = 3232235520 && $ip = 4294967040]
            return false;
    }
    return true;
}

answered Jan 29, 2015 at 14:37

manuelbcdmanuelbcd

2,6801 gold badge23 silver badges37 bronze badges

6

The answer is to use $_SERVER variable. For example, $_SERVER["REMOTE_ADDR"] would return the client's IP address.

tjhorner

3512 silver badges16 bronze badges

answered Jun 9, 2010 at 4:56

kainosnouskainosnous

5583 silver badges5 bronze badges

0

A quick solution [error free]

function getClientIP[]:string
{
    $keys=array['HTTP_CLIENT_IP','HTTP_X_FORWARDED_FOR','HTTP_X_FORWARDED','HTTP_FORWARDED_FOR','HTTP_FORWARDED','REMOTE_ADDR'];
    foreach[$keys as $k]
    {
        if [!empty[$_SERVER[$k]] && filter_var[$_SERVER[$k], FILTER_VALIDATE_IP]]
        {
            return $_SERVER[$k];
        }
    }
    return "UNKNOWN";
}

hanshenrik

18.1k3 gold badges39 silver badges77 bronze badges

answered Jun 23, 2019 at 8:04

3

function get_client_ip[]
{
    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]] {
            foreach [explode[',', $_SERVER[$key]] as $ip] {
                $ip = trim[$ip];
                if [[bool] filter_var[$ip, FILTER_VALIDATE_IP,
                                FILTER_FLAG_IPV4 |
                                FILTER_FLAG_NO_PRIV_RANGE |
                                FILTER_FLAG_NO_RES_RANGE]] {
                    return $ip;
                }
            }
        }
    }
    return null;
}

Or the compressed version:

function get_ip[] {
    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 [array_map['trim', explode[',', $_SERVER[$key]]] as $ip] {
                if [filter_var[$ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE] !== false] {
                    return $ip;
                }
            }
        }
    }
}

answered May 20, 2019 at 13:58

KeaserKeaser

3313 silver badges6 bronze badges

Here's a bit of code that should pick a valid IP by checking through various sources.

First, it checks if 'REMOTE_ADDR' is a public IP or not [and not one of your trusted reverse proxies], then goes through one of the HTTP headers until it finds a public IP and returns it. [PHP 5.2+]

It should be reliable as long as the reverse proxy is trusted or the server is directly connected with the client.

//Get client's IP or null if nothing looks valid
function ip_get[$allow_private = false]
{
  //Place your trusted proxy server IPs here.
  $proxy_ip = ['127.0.0.1'];

  //The header to look for [Make sure to pick the one that your trusted reverse proxy is sending or else you can get spoofed]
  $header = 'HTTP_X_FORWARDED_FOR'; //HTTP_CLIENT_IP, HTTP_X_FORWARDED, HTTP_FORWARDED_FOR, HTTP_FORWARDED

  //If 'REMOTE_ADDR' seems to be a valid client IP, use it.
  if[ip_check[$_SERVER['REMOTE_ADDR'], $allow_private, $proxy_ip]] return $_SERVER['REMOTE_ADDR'];

  if[isset[$_SERVER[$header]]]
  {
    //Split comma separated values [1] in the header and traverse the proxy chain backwards.
    //[1] //en.wikipedia.org/wiki/X-Forwarded-For#Format
    $chain = array_reverse[preg_split['/\s*,\s*/', $_SERVER[$header]]];
    foreach[$chain as $ip] if[ip_check[$ip, $allow_private, $proxy_ip]] return $ip;
  }

   return null;
}

//Check for valid IP. If 'allow_private' flag is set to truthy, it allows private IP ranges as valid client IP as well. [10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16]
//Pass your trusted reverse proxy IPs as $proxy_ip to exclude them from being valid.
function ip_check[$ip, $allow_private = false, $proxy_ip = []]
{
  if[!is_string[$ip] || is_array[$proxy_ip] && in_array[$ip, $proxy_ip]] return false;
  $filter_flag = FILTER_FLAG_NO_RES_RANGE;

  if[!$allow_private]
  {
    //Disallow loopback IP range which doesn't get filtered via 'FILTER_FLAG_NO_PRIV_RANGE' [1]
    //[1] //www.php.net/manual/en/filter.filters.validate.php
    if[preg_match['/^127\.$/', $ip]] return false;
    $filter_flag |= FILTER_FLAG_NO_PRIV_RANGE;
  }

  return filter_var[$ip, FILTER_VALIDATE_IP, $filter_flag] !== false;
}

answered Jun 2, 2019 at 7:12

ws-onows-ono

1831 silver badge7 bronze badges

0

As all others said before you can use $_SERVER['REMOTE_ADDR']; to get the client IP address.

Also, if you need more information about a user, you can use this:

Chủ Đề