Skip to content

  • Home
  • Archives
  • Tools
  • Links
  • Guest
  • About

Let's whisper

  • 程序开发
    • PHP
    • Python
    • HTML/CSS
    • JavaScript
    • 服务器
    • 数据库
    • 微信开发
    • 区块链
    • 作品展示
  • 应用程序
    • 开发工具
    • 操作系统
    • 桌面应用
    • 移动应用
    • 网页应用
  • WordPress
  • 探索发现
    • 音乐
    • 影视
    • 图像
    • 资讯
    • 设计创意
    • 新技能
  • 个人日志

Home 程序开发 PHP PHP获取客户端真实IP

PHP获取客户端真实IP

2014/12/10 9,153

代码一:来源于 ThinkPHP 的函数库,我进行了小修改(取X-Forwarded-For中第一个非unknown的有效IP字符串 部分)。通常情况下可用此方法。

/**
 * 获取客户端IP
 * 修改自 ThinkPHP 函数库
 * @staticvar type $ip
 * @return string
 */
function get_client_ip()
{
    static $ip = NULL;
    if ($ip !== NULL)
    {
        return $ip;
    }
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
    {
        /* 取X-Forwarded-For中第一个非unknown的有效IP字符串 */
        $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        foreach ($arr AS $v)
        {
            $ip = trim($v);
            if ($ip != 'unknown')
            {
                break;
            }
        }
    }
    elseif (isset($_SERVER['HTTP_CLIENT_IP']))
    {
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    }
    elseif (isset($_SERVER['REMOTE_ADDR']))
    {
        $ip = $_SERVER['REMOTE_ADDR'];
    }
    // IP地址合法验证 
    $ip = (false !== ip2long($ip)) ? $ip : '0.0.0.0';
    return $ip;
}

代码二:来源于 ECShop 的函数库,比方法一多一重判断,当$_SERVER取不到的情况下(不过目前我还不知道什么情况下会取不到。。),使用 getenv() 函数获取。

/**
 * 获得用户的真实IP地址
 * 来源于 ECShop 函数库
 * @return  string
 */
function real_ip()
{
    static $realip = NULL;
    if ($realip !== NULL)
    {
        return $realip;
    }
    if (isset($_SERVER))
    {
        if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
        {
            $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
            /* 取X-Forwarded-For中第一个非unknown的有效IP字符串 */
            foreach ($arr AS $ip)
            {
                $ip = trim($ip);
                if ($ip != 'unknown')
                {
                    $realip = $ip;
                    break;
                }
            }
        }
        elseif (isset($_SERVER['HTTP_CLIENT_IP']))
        {
            $realip = $_SERVER['HTTP_CLIENT_IP'];
        }
        else
        {
            if (isset($_SERVER['REMOTE_ADDR']))
            {
                $realip = $_SERVER['REMOTE_ADDR'];
            }
            else
            {
                $realip = '0.0.0.0';
            }
        }
    }
    else
    {
        if (getenv('HTTP_X_FORWARDED_FOR'))
        {
            $realip = getenv('HTTP_X_FORWARDED_FOR');
        }
        elseif (getenv('HTTP_CLIENT_IP'))
        {
            $realip = getenv('HTTP_CLIENT_IP');
        }
        else
        {
            $realip = getenv('REMOTE_ADDR');
        }
    }
    preg_match("/[\d\.]{7,15}/", $realip, $onlineip);
    $realip = !empty($onlineip[0]) ? $onlineip[0] : '0.0.0.0';
    return $realip;
}

好了,现在已经得到客户端 IP 了,我们检查一下是否在允许的 IP 或 IP 段内,通过*通配符进行IP段标识。

/**
 * 验证IP是否合法,支持*通配符
 * @return boolean
 */
function is_valid_ip()
{
    $whitelist = array('192.168.*', '127.0.0.1', '192.168.2.49');//IP白名单列表
    $client_ip = '192.168.2.10';//客户端IP
    $valid = true; //标识是否合法的ip
    //不在白名单中
    if (!in_array($client_ip, $whitelist))
    {
        $valid = false;
        foreach ($whitelist as $white)
        {
            //白名单ip含有*通配符
            if (strpos($white, '*') !== false)
            {
                $valid         = true;
                $white_arr     = explode('.', $white); //白名单ip拆分成数组
                $client_ip_arr = explode('.', $client_ip); //要检测的ip拆分成数组
                
                //对应IP段相比较
                foreach ($white_arr as $k => $v)
                {
                    if ($v != '*' && $v != $client_ip_arr[$k])
                    {
                        $valid = false;
                        break;
                    }
                }
                //经过轮番比较后仍然是true,结束循环白名单
                if ($valid == true)
                {
                    break;
                }
            }
        }
    }
    return $valid;
}
Posted in PHP   Tagged IP, PHP, 代码收藏

恰克

本页链接: https://miu.im/?p=425

最近更新: 2014/12/12

Previous Post: PHP友好变量输出
Next Post: 为文章生成二维码

Primary Sidebar

相关文章

  • PHP 处理URL的函数
  • PHP友好变量输出
  • PHP抽奖概率算法
  • max_input_vars
  • LNMP 下使用 ThinkPHP5 连接远程 Oracle 数据库

近期文章

  • 您好,2021
  • max_input_vars
  • 提升效率的几个 VSCode 快捷键
  • TA-Lib Installation
  • iPhone 使用的几个小技巧
  • 再次回归
  • Visual Studio Code disable auto wrap long line
  • KeePass 复制条目到另一个数据库
  • Chrome DevTools 小技巧两则
  • 区块链投资
Loading

功能

  • 登录
  • 条目feed
  • 评论feed
  • WordPress.org

Copyright © 2009-2023 Let's whisper. Powered by WordPress and Stargazer.