php 如何从访客那里获得真实IP?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13646690/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 05:50:41  来源:igfitidea点击:

How to get Real IP from Visitor?

phpip

提问by

I'm using this PHP code to get a visitor's IP address:

我正在使用此 PHP 代码来获取访问者的 IP 地址:

<?php echo $_SERVER['REMOTE_ADDR']; ?>

But, I can't get the real IP address from visitors when they are using a proxy. Is there any way to get a visitor's IP address in this case?

但是,访问者使用代理时,我无法从访问者那里获取真实 IP 地址。在这种情况下,有没有办法获取访问者的 IP 地址?

回答by

Try this php code.

试试这个 php 代码。

<?PHP

function getUserIP()
{
    // Get real visitor IP behind CloudFlare network
    if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) {
              $_SERVER['REMOTE_ADDR'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
              $_SERVER['HTTP_CLIENT_IP'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
    }
    $client  = @$_SERVER['HTTP_CLIENT_IP'];
    $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
    $remote  = $_SERVER['REMOTE_ADDR'];

    if(filter_var($client, FILTER_VALIDATE_IP))
    {
        $ip = $client;
    }
    elseif(filter_var($forward, FILTER_VALIDATE_IP))
    {
        $ip = $forward;
    }
    else
    {
        $ip = $remote;
    }

    return $ip;
}


$user_ip = getUserIP();

echo $user_ip; // Output IP address [Ex: 177.87.193.134]


?>

回答by Teneff

This is the most common technique I've seen:

这是我见过的最常见的技术:

function getUserIP() {
    if( array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER) && !empty($_SERVER['HTTP_X_FORWARDED_FOR']) ) {
        if (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',')>0) {
            $addr = explode(",",$_SERVER['HTTP_X_FORWARDED_FOR']);
            return trim($addr[0]);
        } else {
            return $_SERVER['HTTP_X_FORWARDED_FOR'];
        }
    }
    else {
        return $_SERVER['REMOTE_ADDR'];
    }
}

Note that it does not guarantee it you will get always the correct user IP because there are many ways to hide it.

请注意,它不保证您将始终获得正确的用户 IP,因为有很多方法可以隐藏它。

回答by El cero

This is my approach:

这是我的方法:

 function getRealUserIp(){
    switch(true){
      case (!empty($_SERVER['HTTP_X_REAL_IP'])) : return $_SERVER['HTTP_X_REAL_IP'];
      case (!empty($_SERVER['HTTP_CLIENT_IP'])) : return $_SERVER['HTTP_CLIENT_IP'];
      case (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) : return $_SERVER['HTTP_X_FORWARDED_FOR'];
      default : return $_SERVER['REMOTE_ADDR'];
    }
 }

How to use:

如何使用:

$ip = getRealUserIp();

回答by Halcyon

Proxies may send a HTTP_X_FORWARDED_FORheader but even that is optional.

代理可能会发送一个HTTP_X_FORWARDED_FOR标头,但这也是可选的。

Also keep in mind that visitors may share IP addresses; University networks, large companies and third-world/low-budget ISPs tend to share IPs over many users.

还要记住,访问者可能会共享 IP 地址;大学网络、大公司和第三世界/低预算 ISP 倾向于在许多用户之间共享 IP。

回答by Yogesh Prajapati

apply this code for get the ipaddress:

应用此代码获取 ipaddress:

    if (getenv('HTTP_X_FORWARDED_FOR')) { $pipaddress = getenv('HTTP_X_FORWARDED_FOR');
 $ipaddress = getenv('REMOTE_ADDR'); 
    echo "Your Proxy IP address is : ".$pipaddress. "(via $ipaddress)" ; } 
    else { $ipaddress = getenv('REMOTE_ADDR'); echo "Your IP address is : $ipaddress"; }
    ------------------------------------------------------------------------

回答by Ehsan Chavoshi

This is my function.

这是我的职能。

benefits :

好处 :

  • Work if $_SERVER was not available.
  • Filter private and/or reserved IPs;
  • Process all forwarded IPs in X_FORWARDED_FOR
  • Compatible with CloudFlare
  • Can set a default if no valid IP found!
  • Short & Simple !
  • 如果 $_SERVER 不可用,则工作。
  • 过滤私有和/或保留 IP;
  • 处理 X_FORWARDED_FOR 中所有转发的 IP
  • 与 CloudFlare 兼容
  • 如果找不到有效的 IP,可以设置默认值!
  • 简短而简单!


/**
 * Get real user ip
 *
 * Usage sample:
 * GetRealUserIp();
 * GetRealUserIp('ERROR',FILTER_FLAG_NO_RES_RANGE);
 * 
 * @param string $default default return value if no valid ip found
 * @param int    $filter_options filter options. default is FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE
 *
 * @return string real user ip
 */

function GetRealUserIp($default = NULL, $filter_options = 12582912) {
    $HTTP_X_FORWARDED_FOR = isset($_SERVER)? $_SERVER["HTTP_X_FORWARDED_FOR"]:getenv('HTTP_X_FORWARDED_FOR');
    $HTTP_CLIENT_IP = isset($_SERVER)?$_SERVER["HTTP_CLIENT_IP"]:getenv('HTTP_CLIENT_IP');
    $HTTP_CF_CONNECTING_IP = isset($_SERVER)?$_SERVER["HTTP_CF_CONNECTING_IP"]:getenv('HTTP_CF_CONNECTING_IP');
    $REMOTE_ADDR = isset($_SERVER)?$_SERVER["REMOTE_ADDR"]:getenv('REMOTE_ADDR');

    $all_ips = explode(",", "$HTTP_X_FORWARDED_FOR,$HTTP_CLIENT_IP,$HTTP_CF_CONNECTING_IP,$REMOTE_ADDR");
    foreach ($all_ips as $ip) {
        if ($ip = filter_var($ip, FILTER_VALIDATE_IP, $filter_options))
            break;
    }
    return $ip?$ip:$default;
}

回答by Nick Tsai

If the Proxy is which you trust, you can try: (Assume the Proxy IP is 151.101.2.10)

如果代理是您信任的,您可以尝试:(假设代理 IP 是151.101.2.10

<?php

$trustProxyIPs = ['151.101.2.10'];

$clientIP  = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : NULL;

if (in_array($clientIP, $trustProxyIPs)) {

    $headers = ['HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR'];

    foreach ($headers as $key => $header) {

        if (isset($_SERVER[$header]) && filter_var($_SERVER[$header], FILTER_VALIDATE_IP)) {

            $clientIP = $_SERVER[$header];

            break;
        }
    }
}

echo $clientIP;

This will prevent forged forward header by direct requested clients, and get real IP via trusted Proxies.

这将防止直接请求的客户端伪造转发头,并通过受信任的代理获取真实 IP。

回答by Nelson

Yes, $_SERVER["HTTP_X_FORWARDED_FOR"]is how I see my ip when under a proxy on my nginx server.

是的,这$_SERVER["HTTP_X_FORWARDED_FOR"]就是我在 nginx 服务器上的代理下看到我的 ip 的方式。

But your best bet is to run phpinfo()on a page requested from under a proxy so you can look at all the availabe variables and see what is the one that carries your real ip.

但是最好的办法是phpinfo()在代理下请求的页面上运行,这样您就可以查看所有可用变量并查看携带您真实 IP 的变量。

回答by Valcone

This works for Windows and Linux! It doesn't matter if it's localhost or online..

这适用于 Windows 和 Linux!无论是本地主机还是在线都没关系..

    function getIP() {
    $ip = $_SERVER['SERVER_ADDR'];

    if (PHP_OS == 'WINNT'){
        $ip = getHostByName(getHostName());
    }

    if (PHP_OS == 'Linux'){
        $command="/sbin/ifconfig";
        exec($command, $output);
        // var_dump($output);
        $pattern = '/inet addr:?([^ ]+)/';

        $ip = array();
        foreach ($output as $key => $subject) {
            $result = preg_match_all($pattern, $subject, $subpattern);
            if ($result == 1) {
                if ($subpattern[1][0] != "127.0.0.1")
                $ip = $subpattern[1][0];
            }
        //var_dump($subpattern);
        }
    }
    return $ip;
}