zoukankan      html  css  js  c++  java
  • PHP获取用户客户端真实IP的解决方案是怎样呢?

    function getIp(){
    if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown"))
    $ip = getenv("HTTP_CLIENT_IP");
    else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown"))
    $ip = getenv("HTTP_X_FORWARDED_FOR");
    else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown"))
    $ip = getenv("REMOTE_ADDR");
    else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown"))
    $ip = $_SERVER['REMOTE_ADDR'];
    else
    $ip = "unknown";
    return($ip);

    现在需要对这段代码进行解释,这里用到了两个函数,getenv()和strcasecmp(),前一个函数获取得系统的环境变量,如果能取到值,则返回该值,不能则返回false.

    $_SERVER是服务器超级全局变量数组,用$_SERVER['REMOTE_ADDR']同样可以获取到客户端的IP地址.二者的区别在于,getenv不支持IIS的isapi方式运行的php.

    strcasecmp(string1,string2)字符串函数的用法是把string1和string2进行比较,如果相等返回0,如果string1大于string2,返回大于0的数,小于则返回小于0的数.

    函数先使用客户IP,如果不成立尝试用代理的方法,如果不行,再使用REMOTE_ADDR.

    还看到过一个检测IP更详细的方法,考虑了IP的欺骗,和多重代理代码.方法相类似.

    function getip() {
    $unknown = 'unknown';
    if ( isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] && strcasecmp($_SERVER['HTTP_X_FORWARDED_FOR'], $unknown) ) {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    } elseif ( isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], $unknown) ) {
    $ip = $_SERVER['REMOTE_ADDR'];
    }
    /*
    处理多层代理的情况
    或者使用正则方式:$ip = preg_match("/[d.]{7,15}/", $ip, $matches) ? $matches[0] : $unknown;
    */
    if (false !== strpos($ip, ','))
    $ip = reset(explode(',', $ip));
    return $ip;
    }

    一、没有使用代理服务器的PHP获取客户端IP情况:

    REMOTE_ADDR = 客户端IP
    HTTP_X_FORWARDED_FOR = 没数值或不显示

    二、使用透明代理服务器的情况:Transparent Proxies

    REMOTE_ADDR = 最后一个代理服务器 IP
    HTTP_X_FORWARDED_FOR = 客户端真实 IP (经过多个代理服务器时,这个值类似:221.5.252.160, 203.98.182.163, 203.129.72.215)

    这类代理服务器还是将客户端真实的IP发送给了访问对象,无法达到隐藏真实身份的目的.

    三、使用普通匿名代理服务器的PHP获取客户端IP情况:Anonymous Proxies

    REMOTE_ADDR = 最后一个代理服务器 IP
    HTTP_X_FORWARDED_FOR = 代理服务器 IP (经过多个代理服务器时,这个值类似:203.98.182.163, 203.98.182.163, 203.129.72.215)

    这种情况下隐藏了客户端的真实IP,但是向访问对象透露了客户端是使用代理服务器访问它们的.

    四、使用欺骗性代理服务器的情况:Distorting Proxies

    REMOTE_ADDR = 代理服务器 IP
    HTTP_X_FORWARDED_FOR = 随机的 IP(经过多个代理服务器时,这个值类似:220.4.251.159, 203.98.182.163, 203.129.72.215)

    这种情况下同样透露了客户端是使用了代理服务器,但编造了一个虚假的随机IP(220.4.251.159)代替客户端的真实IP来欺骗它.

    五、使用高匿名代理服务器的PHP获取客户端IP情况:High Anonymity Proxies (Elite proxies)

    REMOTE_ADDR = 代理服务器 IP

    HTTP_X_FORWARDED_FOR = 没数值或不显示

    无论是REMOTE_ADDR还是HTTP_FORWARDED_FOR,这些头消息未必能够取得到,因为不同的浏览器不同的网络设备可能发送不同的IP头消息.因此PHP使用$_SERVER["REMOTE_ADDR"] 、$_SERVER["HTTP_X_FORWARDED_FOR"] 获取的值可能是空值也可能是“unknown”值.

    function substring($str, $start, $length){ //比较好用字符串截取函数
    $len = $length;
    if($length < 0){
    $str = strrev($str);
    $len = -$length;
    }
    $len= ($len < strlen($str)) ? $len : strlen($str);
    $tmpstr = "";
    for ($i= $start; $i < $len; $i ++)
    {
    if (ord(substr($str, $i, 1)) > 0xa0)
    {
    $tmpstr .= substr($str, $i, 2);
    $i++;
    } else {
    $tmpstr .= substr($str, $i, 1);
    }
    }
    if($length < 0) $tmpstr = strrev($tmpstr);
    return $tmpstr;
    }

    使用方法示例:

    $str1 = '我是一串比较长的中文不带英文';
    $str2 = '我是一串比较长的中文带yingwen';
    $len = strlen($str1);
    echo '<br />'.$len; //return 28
    $len = strlen($str2);
    echo '<br />'.$len; //return 29
    echo '<br />'; 
    echo substring($str1, 0, 11); 
    echo '<br />';
    echo substring($str2, 0, 11); 
    echo '<br />';
    echo substring($str1, 16, 28); 
    echo '<br />';
    echo substring($str2, 16, 29); 

    结果显示:

    28
    29
    我是一串比较
    我是一串比较
    中文不带英文
    中文带yingwen

    这个函数十分有用,比如用来截断比较长的文件名,但是要在中间加上...,可以这样来做:

    function formatName($str, $size){
    $len = strlen($str);
    if(strlen($str) > $size) {
    $part1 = substring($str, 0, $size / 2);
    $part2 = substring($str, $len - ($size/2), $len);
    return $part1 . "..." . $part2;
    } else {
    return $str;
    }
    }

  • 相关阅读:
    P2572 [SCOI2010]序列操作
    python学习笔记2
    嗯,python
    ETROBOT——审题
    条件编译
    第三章单片机简介
    模拟输入输出
    arduino库函数1
    arduino相关文献阅读
    Arduino的小灯亮起来~~~
  • 原文地址:https://www.cnblogs.com/2881064178dinfeng/p/6179336.html
Copyright © 2011-2022 走看看