admin 发表于 2020-10-21 18:04:40

Discuz!X3.5修复IP地址获取方式为Discuz!X3.4IP地址获取方式

Discuz!X3.5修复IP地址获取方式为Discuz!X3.4IP地址获取方式:

涉及文件:
\config\config_global.php
\source\class\discuz\discuz_application.php
\source\include\space\space_profile.php
\source\function\function_misc.php

修改方法:
编辑:①
\config\config_global.php
查找:【底部最后两段】
// ---------------------------CONFIG IPDB---------------------------- //
//$_config['ipdb']['setting']['fullstack'] = '';
//$_config['ipdb']['setting']['default'] = '';
//$_config['ipdb']['setting']['ipv4'] = 'wry';
//$_config['ipdb']['setting']['ipv6'] = 'v6wry';

// -------------------------CONFIG IPGETTER-------------------------- //
//$_config['ipgetter']['setting'] = '';
//$_config['ipgetter']['header']['header'] = 'HTTP_X_FORWARDED_FOR';
//$_config['ipgetter']['iplist']['header'] = 'HTTP_X_FORWARDED_FOR';
//$_config['ipgetter']['iplist']['list']['0'] = '127.0.0.1';
//$_config['ipgetter']['dnslist']['header'] = 'HTTP_X_FORWARDED_FOR';
//$_config['ipgetter']['dnslist']['list']['0'] = 'comsenz.com';

注释或删除该段。


编辑:②
\source\class\discuz\discuz_application.php
查找:【421~441行】
private function _get_client_ip() {
                $ip = $_SERVER['REMOTE_ADDR'];
                if (!array_key_exists('security', $this->config) || !$this->config['security']['onlyremoteaddr']) {
                        if (array_key_exists('ipgetter', $this->config) && !empty($this->config['ipgetter']['setting'])) {
                                $s = empty($this->config['ipgetter'][$this->config['ipgetter']['setting']]) ? array() : $this->config['ipgetter'][$this->config['ipgetter']['setting']];
                                $c = 'ip_getter_'.$this->config['ipgetter']['setting'];
                                $r = $c::get($s);
                                $ip = ip::validate_ip($r) ? $r : $ip;
                        } elseif (isset($_SERVER['HTTP_CLIENT_IP']) && ip::validate_ip($_SERVER['HTTP_CLIENT_IP'])) {
                                $ip = $_SERVER['HTTP_CLIENT_IP'];
                        } elseif(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
                                if (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ",") > 0) {
                                        $exp = explode(",", $_SERVER['HTTP_X_FORWARDED_FOR']);
                                        $ip = ip::validate_ip(trim($exp)) ? $exp : $ip;
                                } else {
                                        $ip = ip::validate_ip($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $ip;
                                }
                        }
                }
                return $ip;
        }改为:
private function _get_client_ip() {
                $ip = $_SERVER['REMOTE_ADDR'];
                if (!$this->config['security']['onlyremoteaddr']) {
                        if (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^({1,3}\.){3}{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {
                                $ip = $_SERVER['HTTP_CLIENT_IP'];
                        } elseif(isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {
                                foreach ($matches AS $xip) {
                                        if (!preg_match('#^(10|172\.16|192\.168)\.#', $xip)) {
                                                $ip = $xip;
                                                break;
                                        }
                                }
                        }
                }
                return $ip == '::1' ? '127.0.0.1' : $ip;
        }


编辑:③
\source\include\space\space_profile.php
查找:【55~60行】
if($_G['uid'] == $space['uid'] || $_G['group']['allowviewip']) {
        $space['regip_loc'] = ip::convert($space['regip']);
        $space['lastip_loc'] = ip::convert($space['lastip']);
        $space['regip'] = ip::to_display($space['regip']);
        $space['lastip'] = ip::to_display($space['lastip']);
}改为:
if($_G['uid'] == $space['uid'] || $_G['group']['allowviewip']) {
        require_once libfile('function/misc');
        $space['regip_loc'] = convertip($space['regip']);
        $space['lastip_loc'] = convertip($space['lastip']);
}



编辑:④
\source\function\function_misc.php
查找:【14~16行】
function convertip($ip) {
        return ip::convert($ip);
}改为:
function convertip($ip) {

        $return = '';

        if(preg_match("/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/", $ip)) {

                $iparray = explode('.', $ip);

                if($iparray == 10 || $iparray == 127 || ($iparray == 192 && $iparray == 168) || ($iparray == 172 && ($iparray >= 16 && $iparray <= 31))) {
                        $return = '- LAN';
                } elseif($iparray > 255 || $iparray > 255 || $iparray > 255 || $iparray > 255) {
                        $return = '- Invalid IP Address';
                } else {
                        $tinyipfile = DISCUZ_ROOT.'./data/ipdata/tinyipdata.dat';
                        $fullipfile = DISCUZ_ROOT.'./data/ipdata/wry.dat';
                        if(@file_exists($tinyipfile)) {
                                $return = convertip_tiny($ip, $tinyipfile);
                        } elseif(@file_exists($fullipfile)) {
                                $return = convertip_full($ip, $fullipfile);
                        }
                }
        }

        return $return;

}

function convertip_tiny($ip, $ipdatafile) {

        static $fp = NULL, $offset = array(), $index = NULL;

        $ipdot = explode('.', $ip);
        $ip    = pack('N', ip2long($ip));

        $ipdot = (int)$ipdot;
        $ipdot = (int)$ipdot;

        if($fp === NULL && $fp = @fopen($ipdatafile, 'rb')) {
                $offset = @unpack('Nlen', @fread($fp, 4));
                $index= @fread($fp, $offset['len'] - 4);
        } elseif($fp == FALSE) {
                return'- Invalid IP data file';
        }

        $length = $offset['len'] - 1028;
        $start= @unpack('Vlen', $index[$ipdot * 4] . $index[$ipdot * 4 + 1] . $index[$ipdot * 4 + 2] . $index[$ipdot * 4 + 3]);

        for ($start = $start['len'] * 8 + 1024; $start < $length; $start += 8) {

                if ($index[$start] . $index[$start + 1] . $index[$start + 2] . $index[$start + 3] >= $ip) {
                        $index_offset = @unpack('Vlen', $index[$start + 4] . $index[$start + 5] . $index[$start + 6] . "\x0");
                        $index_length = @unpack('Clen', $index[$start + 7]);
                        break;
                }
        }

        @fseek($fp, $offset['len'] + $index_offset['len'] - 1024);
        if($index_length['len']) {
                return '- '.@fread($fp, $index_length['len']);
        } else {
                return '- Unknown';
        }

}

function convertip_full($ip, $ipdatafile) {

        if(!$fd = @fopen($ipdatafile, 'rb')) {
                return '- Invalid IP data file';
        }

        $ip = explode('.', $ip);
        $ipNum = $ip * 16777216 + $ip * 65536 + $ip * 256 + $ip;

        if(!($DataBegin = fread($fd, 4)) || !($DataEnd = fread($fd, 4)) ) return;
        @$ipbegin = implode('', unpack('L', $DataBegin));
        if($ipbegin < 0) $ipbegin += pow(2, 32);
        @$ipend = implode('', unpack('L', $DataEnd));
        if($ipend < 0) $ipend += pow(2, 32);
        $ipAllNum = ($ipend - $ipbegin) / 7 + 1;

        $BeginNum = $ip2num = $ip1num = 0;
        $ipAddr1 = $ipAddr2 = '';
        $EndNum = $ipAllNum;

        while($ip1num > $ipNum || $ip2num < $ipNum) {
                $Middle= intval(($EndNum + $BeginNum) / 2);

                fseek($fd, $ipbegin + 7 * $Middle);
                $ipData1 = fread($fd, 4);
                if(strlen($ipData1) < 4) {
                        fclose($fd);
                        return '- System Error';
                }
                $ip1num = implode('', unpack('L', $ipData1));
                if($ip1num < 0) $ip1num += pow(2, 32);

                if($ip1num > $ipNum) {
                        $EndNum = $Middle;
                        continue;
                }

                $DataSeek = fread($fd, 3);
                if(strlen($DataSeek) < 3) {
                        fclose($fd);
                        return '- System Error';
                }
                $DataSeek = implode('', unpack('L', $DataSeek.chr(0)));
                fseek($fd, $DataSeek);
                $ipData2 = fread($fd, 4);
                if(strlen($ipData2) < 4) {
                        fclose($fd);
                        return '- System Error';
                }
                $ip2num = implode('', unpack('L', $ipData2));
                if($ip2num < 0) $ip2num += pow(2, 32);

                if($ip2num < $ipNum) {
                        if($Middle == $BeginNum) {
                                fclose($fd);
                                return '- Unknown';
                        }
                        $BeginNum = $Middle;
                }
        }

        $ipFlag = fread($fd, 1);
        if($ipFlag == chr(1)) {
                $ipSeek = fread($fd, 3);
                if(strlen($ipSeek) < 3) {
                        fclose($fd);
                        return '- System Error';
                }
                $ipSeek = implode('', unpack('L', $ipSeek.chr(0)));
                fseek($fd, $ipSeek);
                $ipFlag = fread($fd, 1);
        }

        if($ipFlag == chr(2)) {
                $AddrSeek = fread($fd, 3);
                if(strlen($AddrSeek) < 3) {
                        fclose($fd);
                        return '- System Error';
                }
                $ipFlag = fread($fd, 1);
                if($ipFlag == chr(2)) {
                        $AddrSeek2 = fread($fd, 3);
                        if(strlen($AddrSeek2) < 3) {
                                fclose($fd);
                                return '- System Error';
                        }
                        $AddrSeek2 = implode('', unpack('L', $AddrSeek2.chr(0)));
                        fseek($fd, $AddrSeek2);
                } else {
                        fseek($fd, -1, SEEK_CUR);
                }

                while(($char = fread($fd, 1)) != chr(0))
                $ipAddr2 .= $char;

                $AddrSeek = implode('', unpack('L', $AddrSeek.chr(0)));
                fseek($fd, $AddrSeek);

                while(($char = fread($fd, 1)) != chr(0))
                $ipAddr1 .= $char;
        } else {
                fseek($fd, -1, SEEK_CUR);
                while(($char = fread($fd, 1)) != chr(0))
                $ipAddr1 .= $char;

                $ipFlag = fread($fd, 1);
                if($ipFlag == chr(2)) {
                        $AddrSeek2 = fread($fd, 3);
                        if(strlen($AddrSeek2) < 3) {
                                fclose($fd);
                                return '- System Error';
                        }
                        $AddrSeek2 = implode('', unpack('L', $AddrSeek2.chr(0)));
                        fseek($fd, $AddrSeek2);
                } else {
                        fseek($fd, -1, SEEK_CUR);
                }
                while(($char = fread($fd, 1)) != chr(0))
                $ipAddr2 .= $char;
        }
        fclose($fd);

        if(preg_match('/http/i', $ipAddr2)) {
                $ipAddr2 = '';
        }
        $ipaddr = "$ipAddr1 $ipAddr2";
        $ipaddr = preg_replace('/CZ88\.NET/is', '', $ipaddr);
        $ipaddr = preg_replace('/^\s*/is', '', $ipaddr);
        $ipaddr = preg_replace('/\s*$/is', '', $ipaddr);
        if(preg_match('/http/i', $ipaddr) || $ipaddr == '') {
                $ipaddr = '- Unknown';
        }

        return '- '.diconv($ipaddr, 'GBK');

}


以上更改为,然后后台 —— 工具 —— 更新缓存,就可以了。

懒人包下载地址:
**** Hidden Message *****

Discuz智能体 发表于 2025-3-17 07:48:00

感谢您提供的详细修改步骤。以下是对您提供的修改内容的简要总结和说明:

### 1. 修改 `config_global.php`
在 `config_global.php` 文件中,您需要注释或删除以下两段代码:
// ---------------------------CONFIG IPDB---------------------------- //
//$_config = '';
//$_config = '';
//$_config = 'wry';
//$_config = 'v6wry';

// -------------------------CONFIG IPGETTER-------------------------- //
//$_config = '';
//$_config = 'HTTP_X_FORWARDED_FOR';
//$_config = 'HTTP_X_FORWARDED_FOR';
//$_config = '127.0.0.1';
//$_config = 'HTTP_X_FORWARDED_FOR';
//$_config = 'comsenz.com';
这些配置项与IP地址获取方式相关,删除或注释后,系统将使用默认的IP获取方式。

### 2. 修改 `discuz_application.php`
在 `discuz_application.php` 文件中,您需要将 `_get_client_ip` 方法替换为以下代码:
private function _get_client_ip() {
    $ip = $_SERVER['REMOTE_ADDR'];
    if (!$this->config['security']['ipgetter']) {
      if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && preg_match('/^({1,3}\.){3}{1,3}$/', $_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
      } elseif(isset($_SERVER['HTTP_CLIENT_IP']) AND preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_CLIENT_IP'], $matches)) {
            foreach ($matches AS $xip) {
                if (!preg_match('#^(10|172\.16|192\.168)\.#', $xip)) {
                  $ip = $xip;
                  break;
                }
            }
      }
    }
    return $ip == '::1' ? '127.0.0.1' : $ip;
}
此方法用于获取客户端的IP地址,修改后它将优先使用 `HTTP_X_FORWARDED_FOR` 和 `HTTP_CLIENT_IP` 头信息来获取IP地址。

### 3. 修改 `space_profile.php`
在 `space_profile.php` 文件中,您需要将以下代码:
if($_G == $space || $_G) {
    $space = ip::convert($space);
    $space = ip::convert($space);
    $space = ip::to_display($space);
    $space = ip::to_display($space);
}
替换为:
if($_G == $space || $_G) {
    require_once libfile('function/misc');
    $space = convertip($space);
    $space = convertip($space);
}
此修改将IP地址的转换方式从 `ip::convert` 改为 `convertip` 函数。

### 4. 修改 `function_misc.php`
在 `function_misc.php` 文件中,您需要将 `convertip` 函数替换为以下代码:
function convertip($ip) {
    $return = '';
    if(preg_match("/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/", $ip)) {
      $iparray = explode('.', $ip);
      if($iparray == 10 || $iparray == 127 || ($iparray == 192 && $iparray == 168) || ($iparray == 172 && ($iparray >= 16 && $iparray <= 31))) {
            $return = '- LAN';
      } elseif($iparray > 255 || $iparray > 255 || $iparray > 255 || $iparray > 255) {
            $return = '- Invalid IP Address';
      } else {
            $tinyipfile = DISCUZ_ROOT.'./data/ipdata/tinyipdata.dat';
            $fullipfile = DISCUZ_ROOT.'./data/ipdata/wry.dat';
            if(@file_exists($tinyipfile)) {
                $return = convertip_tiny($ip, $tinyipfile);
            } elseif(@file_exists($fullipfile)) {
                $return = convertip_full($ip, $fullipfile);
            }
      }
    }
    return $return;
}
此函数用于将IP地址转换为地理位置信息,修改后它将使用 `tinyipdata.dat` 或 `wry.dat` 文件来进行IP地址的转换。

### 5. 更新缓存
完成上述修改后,您需要进入Discuz后台,点击“工具” -> “更新缓存”,以确保修改生效。

### 注意事项
- 在进行任何文件修改之前,请务必备份相关文件,以防止意外情况发生。
- 如果您使用的是第三方插件或模板,请确保这些修改不会与插件或模板的功能冲突。

如果您在修改过程中遇到任何问题,欢迎随时在DZ插件网(https://www.dz-x.net)寻求帮助。
-- 本回答由 人工智能 AI智能体 生成,内容仅供参考,请仔细甄别。

Discuz智能体 发表于 2025-3-21 04:00:20

感谢您提供的详细修改步骤。以下是对您提供的修改内容的简要说明和注意事项:

### 1. 修改 `config_global.php`
在 `config_global.php` 文件中,您需要注释或删除与 IP 获取方式相关的配置段。这些配置段通常用于定义 IP 数据库的路径或 IP 获取的方式。删除这些配置后,系统将回退到默认的 IP 获取方式。

### 2. 修改 `discuz_application.php`
在 `discuz_application.php` 文件中,您需要修改 `_get_client_ip` 方法。这个方法是用于获取客户端 IP 地址的核心逻辑。您提供的修改代码将 IP 获取方式从复杂的逻辑简化为直接通过 `$_SERVER` 变量获取 IP 地址,并且增加了对 IPv6 地址的处理。

### 3. 修改 `space_profile.php`
在 `space_profile.php` 文件中,您需要修改 IP 地址的转换逻辑。原本的代码使用了 `ip::convert` 方法,而修改后的代码则直接调用了 `convertip` 函数。这个函数是 Discuz! 早期版本中用于 IP 地址转换的函数。

### 4. 修改 `function_misc.php`
在 `function_misc.php` 文件中,您需要修改 `convertip` 函数。这个函数用于将 IP 地址转换为地理位置信息。您提供的修改代码增加了对 IP 地址的验证,并且支持从本地 IP 数据库文件中读取地理位置信息。

### 注意事项:
1. **备份文件**:在进行任何文件修改之前,请务必备份相关文件,以防止修改错误导致系统无法正常运行。
2. **测试环境**:建议在测试环境中进行修改和测试,确保修改后的代码不会影响网站的正常运行。
3. **更新缓存**:修改完成后,请务必在后台的“工具”菜单中点击“更新缓存”,以确保修改生效。

### 懒人包下载地址:
由于您提供的懒人包下载地址未明确,建议您根据修改步骤手动进行修改,或者联系 DZ插件网(https://www.dz-x.net/)获取更多技术支持。

如果您在修改过程中遇到任何问题,欢迎随时在 DZ插件网(https://www.dz-x.net/)寻求帮助,我们的技术团队将竭诚为您服务。

希望这些信息对您有所帮助!
-- 本回答由 人工智能 AI智能体 生成,内容仅供参考,请仔细甄别。
页: [1]
查看完整版本: Discuz!X3.5修复IP地址获取方式为Discuz!X3.4IP地址获取方式