php判断用户IP网上有好多方法,我今天总结出其中一种方法利用IP数据包
代码如下:
- <?php
- //获取访客真实IP
- function getip()
- {
- if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown'))
- {
- $ip = getenv('HTTP_CLIENT_IP');
- }
- elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown'))
- {
- $ip = getenv('HTTP_X_FORWARDED_FOR');
- }
- elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown'))
- {
- $ip = getenv('REMOTE_ADDR');
- }
- elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown'))
- {
- $ip = $_SERVER['REMOTE_ADDR'];
- }
- return preg_match("/[\d\.]{7,15}/", $ip, $matches) ? $matches[0] : 'unknown';
- }
- //===================================
- //
- // 功能:IP地址获取真实地址函数
- // 参数:$ip - IP地址
- // 作者:[Discuz!] (C) Comsenz Inc.
- //
- //===================================
- function convertip($ip) {
- //IP数据文件路径 注意大小写
- $dat_path = './qqwry.dat';
- //检查IP地址
- if(!ereg("^([0-9]{1,3}.){3}[0-9]{1,3}$", $ip)){
- return 'IP Address Error';
- }
- //打开IP数据文件
- if(!$fd = @fopen($dat_path, 'rb')){
- return 'IP date file not exists or access denied';
- }
- //分解IP进行运算,得出×××数
- $ip = explode('.', $ip);
- $ipNum = $ip[0] * 16777216 + $ip[1] * 65536 + $ip[2] * 256 + $ip[3];
- //获取IP数据索引开始和结束位置
- $DataBegin = fread($fd, 4);
- $DataEnd = fread($fd, 4);
- $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 = 0;
- $EndNum = $ipAllNum;
- //使用二分查找法从索引记录中搜索匹配的IP记录
- while($ip1num>$ipNum || $ip2num<$ipNum) {
- $Middle= intval(($EndNum + $BeginNum) / 2);
- //偏移指针到索引位置读取4个字节
- fseek($fd, $ipbegin + 7 * $Middle);
- $ipData1 = fread($fd, 4);
- if(strlen($ipData1) < 4) {
- fclose($fd);
- return 'System Error';
- }
- //提取出来的数据转换成长×××,如果数据是负数则加上2的32次幂
- $ip1num = implode('', unpack('L', $ipData1));
- if($ip1num < 0) $ip1num += pow(2, 32);
- //提取的长整型数大于我们IP地址则修改结束位置进行下一次循环
- 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 $ipaddr;
- }
- $ip=getip();
- $area=convertip($ip);
- //IP白名单
- $king_oasis_ip_array = array( "127.0.0.2",
- "58.221.100.174",
- "58.221.100.170",
- "58.221.113.130",
- "58.221.140.94",
- "58.221.113.242",
- "58.221.113.238",
- "116.236.228.62",
- "116.236.164.190",
- "116.236.228.50",
- "180.169.34.226",
- "116.226.6.218",
- "116.228.216.254",
- "27.115.108.210"
- );
- if((strpos($area,'上海')!==false)&&($_SERVER['HTTP_REFERER']=='')&&(!in_array($ip, $king_oasis_ip_array)))
- {
- header('Location:403.html');
- exit;
- }
- else
- {
- header('Location:index.html');
- echo file_get_contents('./index.html');//针对织梦等有生成静态页的,如果是wordpress,这一句和下一句不要
- exit;
- }
- ?>
限制上海地区IP访问 并通过白名单中的IP。
本地IP数据包下载 http://down.51cto.com/data/677150
转载于:https://blog.51cto.com/hnllyrp/1130188