web-dev-qa-db-fra.com

Comment obtenir l'adresse IP du client dans PHP

Comment puis-je obtenir l'adresse IP du client en utilisant PHP?

Je souhaite conserver une trace de l'utilisateur qui s'est connecté à mon site Web via son adresse IP.

1106
Anup Prakash

Quoi que vous fassiez, veillez à ne pas faire confiance aux données envoyées par le client. $_SERVER['REMOTE_ADDR'] contient la véritable adresse IP de la partie qui se connecte. C'est la valeur la plus fiable que vous puissiez trouver.

Cependant, ils peuvent se trouver derrière un serveur proxy, auquel cas le proxy peut avoir défini le $_SERVER['HTTP_X_FORWARDED_FOR'], mais cette valeur est facilement falsifiée. Par exemple, il peut être défini par une personne sans proxy, ou l'adresse IP peut être une adresse IP interne du réseau local située derrière le proxy.

Cela signifie que si vous voulez enregistrer le $_SERVER['HTTP_X_FORWARDED_FOR'], assurez-vous de également enregistrer la valeur $_SERVER['REMOTE_ADDR']. Par exemple. en enregistrant les deux valeurs dans différents champs de votre base de données.

Si vous souhaitez enregistrer l'adresse IP dans une base de données sous forme de chaîne, assurez-vous de disposer d'un espace d'au moins 45 caractères . IPv6 est là pour rester et ces adresses sont plus grandes que les anciennes adresses IPv4.

(Notez qu'IPv6 utilise généralement 39 caractères au maximum, mais il existe également une --- notation IPv6 pour les adresses IPv4 qui, sous sa forme complète, peut comporter jusqu'à 45 caractères. Donc, si vous savez ce que vous faites, vous pouvez utilisez 39 caractères, mais si vous voulez simplement le définir et l’oublier, utilisez 45).

1259
Emil Vikström

$_SERVER['REMOTE_ADDR'] peut ne pas contenir réellement d'adresses IP de clients réels, car il vous donnera une adresse proxy pour les clients connectés via un proxy, par exemple. C’est peut-être ce que vous voulez vraiment, selon ce que vous faites avec les IP. L'adresse RFC1918 privée de quelqu'un peut ne pas vous être utile si vous essayez de voir d'où provient votre trafic ou de vous souvenir de l'adresse IP de l'utilisateur auquel l'utilisateur s'est connecté pour la dernière fois, de l'adresse IP publique du proxy ou de NAT. _ la passerelle pourrait être la plus appropriée pour stocker.

Il existe plusieurs en-têtes HTTP tels que X-Forwarded-For qui peuvent ou non être définis par divers proxies. Le problème est que ce ne sont que des en-têtes HTTP qui peuvent être définis par n'importe qui. Il n'y a aucune garantie quant à leur contenu. $_SERVER['REMOTE_ADDR'] est l'adresse IP physique réelle à partir de laquelle le serveur Web a reçu la connexion et à laquelle la réponse sera envoyée. Tout le reste n'est que des informations arbitraires et volontaires. Vous ne pouvez faire confiance à ces informations que dans un seul scénario: vous contrôlez le proxy qui définit cet en-tête. Cela signifie que si vous savez à 100% où et comment l’en-tête a été défini, tenez compte de tout élément important.

Ceci dit, voici un exemple de 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'];
}

Note de l'éditeur: L'utilisation du code ci-dessus a des implications en matière de sécurité . Le client peut définir toutes les informations d'en-tête HTTP (c'est-à-dire $_SERVER['HTTP_...) sur n'importe quelle valeur arbitraire de son choix. En tant que tel, il est beaucoup plus fiable d'utiliser $_SERVER['REMOTE_ADDR'], car cela ne peut pas être défini par l'utilisateur.

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

420
Tim Kennedy
198
lemon

Voici un exemple de code plus propre d'un bon moyen d'obtenir l'adresse IP de l'utilisateur.

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

Voici une version plus courte qui utilise l'opérateur elvis:

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

Voici une version qui utilise isset pour supprimer les notifications (merci @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'];
115
josh123a123

Il devrait être contenu dans la variable $_SERVER['REMOTE_ADDR'].

87
Kyle Cronin

Ma solution préférée est la manière dont Zend Framework 2 utilise. Il considère également les propriétés $_SERVERHTTP_X_FORWARDED_FOR, HTTP_CLIENT_IP, REMOTE_ADDR, mais il déclare une classe pour définir des mandataires sécurisés et renvoie une adresse IP et non un tableau. Je pense que c'est la solution qui s'en rapproche le plus:

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 http://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 http://en.wikipedia.org/wiki/X-Forwarded-For
        $ip = array_pop($ips);
        return $ip;
    }

    // [...]
}

Voir le code complet ici: https://raw.githubusercontent.com/zendframework/zend-http/master/src/PhpEnvironment/RemoteAddress.php

52
algorhythm

Il existe différents types d'utilisateurs derrière Internet. Nous souhaitons donc saisir l'adresse IP de différentes parties. Ce sont:

1. $_SERVER['REMOTE_ADDR'] - Contient la véritable adresse IP du client. C’est la valeur la plus fiable que vous puissiez trouver chez l’utilisateur.

2. $_SERVER['REMOTE_Host'] - Ceci récupérera le nom d'hôte à partir duquel l'utilisateur visualise la page en cours. Mais pour que ce script fonctionne, les recherches de nom d'hôte dans httpd.conf doivent être configurées.

. $_SERVER['HTTP_CLIENT_IP'] - Ceci récupérera l'adresse IP lorsque l'utilisateur est issu de services Internet partagés.

4. $_SERVER['HTTP_X_FORWARDED_FOR'] - Ceci récupérera l'adresse IP de l'utilisateur lorsqu'il se trouve derrière le proxy.

Nous pouvons donc utiliser cette fonction combinée suivante pour obtenir la véritable adresse IP des utilisateurs qui consultent dans différentes 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;
}
44
K.Suthagar

Ce qui suit est la méthode la plus avancée que j'ai trouvée et j'en ai déjà essayé d'autres par le passé. Il est valable de s’assurer d’obtenir l’adresse IP d’un visiteur (mais veuillez noter que tout pirate informatique pourrait facilement falsifier l’adresse IP).

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 <= 50331647)
            return false;
        if ($ip >= 167772160 && $ip <= 184549375)
            return false;
        if ($ip >= 2130706432 && $ip <= 2147483647)
            return false;
        if ($ip >= 2851995648 && $ip <= 2852061183)
            return false;
        if ($ip >= 2886729728 && $ip <= 2887778303)
            return false;
        if ($ip >= 3221225984 && $ip <= 3221226239)
            return false;
        if ($ip >= 3232235520 && $ip <= 3232301055)
            return false;
        if ($ip >= 4294967040)
            return false;
    }
    return true;
}
34
manuelbcd

La réponse est d'utiliser la variable $_SERVER . Par exemple, _$_SERVER["REMOTE_ADDR"]_ renverrait l'adresse IP du client.

30
kainosnous

Comme tous les autres l'ont déjà dit, vous pouvez utiliser $_SERVER['REMOTE_ADDR']; pour obtenir l'adresse IP du client.

De plus, si vous avez besoin de plus d'informations sur un utilisateur, vous pouvez utiliser ceci:

<?php
    $ip = '0.0.0.0';
    $ip = $_SERVER['REMOTE_ADDR'];
    $clientDetails = json_decode(file_get_contents("http://ipinfo.io/$ip/json"));
    echo "You're logged in from: <b>" . $clientDetails->country . "</b>";
?>

Les informations plus spécifiques du client vont dans $ clientDetails.
Vous pouvez récupérer les éléments JSON stockés dans la variable $ clientDetails de la manière suivante: $ clientDetails-> Code postal/nom d'hôte/région/loc ...

J'utilise ipinfo.io pour obtenir des informations supplémentaires.

11
Siamak SiaSoft

C’est la méthode que j’utilise et qui valide une entrée IPv4 :

// Get user IP address
if ( isset($_SERVER['HTTP_CLIENT_IP']) && ! empty($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif ( isset($_SERVER['HTTP_X_FORWARDED_FOR']) && ! empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
    $ip = (isset($_SERVER['REMOTE_ADDR'])) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0';
}

$ip = filter_var($ip, FILTER_VALIDATE_IP);
$ip = ($ip === false) ? '0.0.0.0' : $ip;
10
carbontwelve
$ip = "";

if (!empty($_SERVER["HTTP_CLIENT_IP"]))
{
    // Check for IP address from shared Internet
    $ip = $_SERVER["HTTP_CLIENT_IP"];
}
elseif (!empty($_SERVER["HTTP_X_FORWARDED_FOR"]))
{
    // Check for the proxy user
    $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
}
else
{
    $ip = $_SERVER["REMOTE_ADDR"];
}
echo $ip;
10
Mahfuz Ahmed

Essaye celui-là:

 $_SERVER['REMOTE_ADDR'];

Cela peut être fait simplement en utilisant la variable GLOBAL nommée $_SERVER.

$_SERVER est un tableau portant le nom d'attribut REMOTE_ADDR.

Il suffit de l'assigner comme ceci:

$userIp = $_SERVER['REMOTE_ADDR'];

Ou utilisez-le directement comme echo $_SERVER['REMOTE_ADDR']; ou echo ($_SERVER['REMOTE_ADDR']);.

9
Yash Kumar Verma

J'aime ce codesnippet:

function getClientIP() {

    if (isset($_SERVER)) {

        if (isset($_SERVER["HTTP_X_FORWARDED_FOR"]))
            return $_SERVER["HTTP_X_FORWARDED_FOR"];

        if (isset($_SERVER["HTTP_CLIENT_IP"]))
            return $_SERVER["HTTP_CLIENT_IP"];

        return $_SERVER["REMOTE_ADDR"];
    }

    if (getenv('HTTP_X_FORWARDED_FOR'))
        return getenv('HTTP_X_FORWARDED_FOR');

    if (getenv('HTTP_CLIENT_IP'))
        return getenv('HTTP_CLIENT_IP');

    return getenv('REMOTE_ADDR');
}
9
Johan Wikström

La fonction suivante détermine toutes les possibilités et renvoie les valeurs dans un format séparé par des virgules (ip, ip, etc.).

Il dispose également d'une fonction de validation facultative (premier paramètre désactivé par défaut) pour valider l'adresse IP (plage privée et plage réservée).

<?php
echo GetClientIP(true);

function GetClientIP($validate = False) {
  $ipkeys = array(
  'REMOTE_ADDR',
  'HTTP_CLIENT_IP',
  'HTTP_X_FORWARDED_FOR',
  'HTTP_X_FORWARDED',
  'HTTP_FORWARDED_FOR',
  'HTTP_FORWARDED',
  'HTTP_X_CLUSTER_CLIENT_IP'
  );

  /*
  Now we check each key against $_SERVER if containing such value
  */
  $ip = array();
  foreach ($ipkeys as $keyword) {
    if (isset($_SERVER[$keyword])) {
      if ($validate) {
        if (ValidatePublicIP($_SERVER[$keyword])) {
          $ip[] = $_SERVER[$keyword];
        }
      }
      else{
        $ip[] = $_SERVER[$keyword];
      }
    }
  }

  $ip = ( empty($ip) ? 'Unknown' : implode(", ", $ip) );
  return $ip;
}

function ValidatePublicIP($ip){
  if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
    return true;
  }
  else {
    return false;
  }
}
5
Akam

Cette fonction est compacte et vous pouvez l’utiliser partout. Mais!

N'oublie pas ça! Dans ce type de fonctions ou de blocs de code, il n’ya aucune garantie d’enregistrer l’adresse IP réelle de l’utilisateur car certains utilisateurs peuvent utiliser un proxy ou une autre passerelle sécurisée pour être invisible ou ne peuvent pas effectuer de suivi.

Fonction PHP:

function GetIP()
{
    if ( getenv("HTTP_CLIENT_IP") ) {
        $ip = getenv("HTTP_CLIENT_IP");
    } elseif ( getenv("HTTP_X_FORWARDED_FOR") ) {
        $ip = getenv("HTTP_X_FORWARDED_FOR");
        if ( strstr($ip, ',') ) {
            $tmp = explode(',', $ip);
            $ip = trim($tmp[0]);
        }
    } else {
        $ip = getenv("REMOTE_ADDR");
    }
    return $ip;
}

Usage:

$IP = GetIP(); ou directement GetIP();

5
Ivan Barayev

Extrait sûr et prenant en compte les avertissements pour obtenir l'adresse IP:

$ip = filter_input(INPUT_SERVER, 'HTTP_CLIENT_IP', FILTER_VALIDATE_IP)
    ?: filter_input(INPUT_SERVER, 'HTTP_X_FORWARDED_FOR', FILTER_VALIDATE_IP)
    ?: $_SERVER['REMOTE_ADDR']
    ?? '0.0.0.0'; // Or other value fits "not defined" in your logic
4

Cette fonction devrait fonctionner comme prévu

function Get_User_Ip()
{
    $IP = false;
    if (getenv('HTTP_CLIENT_IP'))
    {
        $IP = getenv('HTTP_CLIENT_IP');
    }
    else if(getenv('HTTP_X_FORWARDED_FOR'))
    {
        $IP = getenv('HTTP_X_FORWARDED_FOR');
    }
    else if(getenv('HTTP_X_FORWARDED'))
    {
        $IP = getenv('HTTP_X_FORWARDED');
    }
    else if(getenv('HTTP_FORWARDED_FOR'))
    {
        $IP = getenv('HTTP_FORWARDED_FOR');
    }
    else if(getenv('HTTP_FORWARDED'))
    {
        $IP = getenv('HTTP_FORWARDED');
    }
    else if(getenv('REMOTE_ADDR'))
    {
        $IP = getenv('REMOTE_ADDR');
    }

    //If HTTP_X_FORWARDED_FOR == server ip
    if((($IP) && ($IP == getenv('SERVER_ADDR')) && (getenv('REMOTE_ADDR')) || (!filter_var($IP, FILTER_VALIDATE_IP))))
    {
        $IP = getenv('REMOTE_ADDR');
    }

    if($IP)
    {
        if(!filter_var($IP, FILTER_VALIDATE_IP))
        {
            $IP = false;
        }
    }
    else
    {
        $IP = false;
    }
    return $IP;
}
2
Mohamad Hamouday

Une solution rapide (sans erreur)

function getClientIP()
{
    $ipaddress = 'UNKNOWN';
    $keys=array('HTTP_CLIENT_IP','HTTP_X_FORWARDED_FOR','HTTP_X_FORWARDED','HTTP_FORWARDED_FOR','HTTP_FORWARDED','REMOTE_ADDR');
    foreach($keys as $k)
    {
        if (isset($_SERVER[$k]) && !empty($_SERVER[$k]) && filter_var($_SERVER[$k], FILTER_VALIDATE_IP))
        {
            $ipaddress = $_SERVER[$k];
            break;
        }
    }
    return $ipaddress;
}
2
Stergios Zg.

Un de ceux-là :

    $ip = $_SERVER['REMOTE_ADDR'];
    $ip = $_SERVER['HTTP_CLIENT_IP'];
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    $ip = $_SERVER['HTTP_X_FORWARDED'];
    $ip = $_SERVER['HTTP_FORWARDED_FOR'];
    $ip = $_SERVER['HTTP_FORWARDED'];
1
SIE

Voici la version one-liner obtenant l'adresse IP du client:

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

Remarques:

  • En utilisant @, il supprime les notifications PHP.
  • La valeur de HTTP_X_FORWARDED_FOR peut comprendre plusieurs adresses séparées par une virgule. Par conséquent, si vous préférez obtenir la première, vous pouvez utiliser la méthode suivante:

    current(explode(',', @$_SERVER['HTTP_X_FORWARDED_FOR']))
    
1
kenorb
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;
} 
1
Masoud Siahkali

Voici un peu de code qui devrait sélectionner une adresse IP valide vérifiant auprès de diverses sources.

Tout d'abord, il vérifie si 'REMOTE_ADDR' est une adresse IP publique ou non (et non l'un de vos mandataires inversés de confiance), puis passe par l'un des en-têtes HTTP jusqu'à ce qu'il trouve une adresse IP publique et la renvoie. (PHP 5.2+)

Il doit être fiable tant que le proxy inverse est approuvé ou que le serveur est directement connecté au 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] https://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] https://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;
}
1
windware-ono
$_SERVER['REMOTE_ADDR'];

Exemple:

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'];
}
0
Suresh Ratten
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;
}

Ou la version compressée:

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;
                }
            }
        }
    }
}

0
nowheretoseek

Juste sur ce point, et je suis surpris que cela n’ait pas encore été mentionné, consiste à obtenir les adresses IP correctes des sites nichés derrière l’infrastructure CloudFlare. Cela cassera vos adresses IP et leur donnera la même valeur. Heureusement, certains en-têtes de serveur sont également disponibles. Au lieu de me réécrire ce qui a déjà été écrit, jetez un coup d'œil ici pour une réponse plus concise, et oui, j'ai déjà suivi ce processus il y a longtemps. https://stackoverflow.com/a/14985633/1190051

0
vr_driver
// Function to get the client ip address
function get_ip() 
{

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'];
}
return $ip;


}
0
user8031209

Voici un simple paquebot

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

MODIFIER:

Le code ci-dessus peut renvoyer adresses réservées (comme 10.0.0.1), un liste d'adresses de tous les serveurs proxy en route, etc. Pour traiter ces cas, utilisez le code suivant:

function valid_ip($ip) {
    // for list of reserved IP addresses, see https://en.wikipedia.org/wiki/Reserved_IP_addresses
    return $ip && substr($ip, 0, 4) != '127.' && substr($ip, 0, 4) != '127.' && substr($ip, 0, 3) != '10.' && substr($ip, 0, 2) != '0.' ? $ip : false;
}

function get_client_ip() {
    // using explode to get only client ip from list of forwarders. see https://en.wikipedia.org/wiki/X-Forwarded-For
    return
    @$_SERVER['HTTP_X_FORWARDED_FOR'] ? explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'], 2)[0] :
    @$_SERVER['HTTP_CLIENT_IP'] ? explode(',', $_SERVER['HTTP_CLIENT_IP'], 2)[0] :
    valid_ip(@$_SERVER['REMOTE_ADDR']) ?:
    'UNKNOWN';
}

echo get_client_ip();
0
oriadam

Comme le suivant?

if (($ip=filter_input(INPUT_SERVER, 'REMOTE_ADDR', validate_ip)) === false or empty($ip)) {
    exit;
}
echo $ip;

PS

if (($ip=filter_input(INPUT_SERVER, 'REMOTE_ADDR', FILTER_VALIDATE_IP|FILTER_FLAG_NO_PRIV_RANGE|FILTER_FLAG_NO_RES_RANGE)) === false) {
    header('HTTP/1.0 400 Bad Request');
    exit;
}

Tous les en-têtes commençant par 'HTTP_' ou 'X-' peuvent être usurpés, est défini par l'utilisateur. Si vous voulez garder une trace, utilisez des cookies, etc.

0
B.F.