>  기사  >  백엔드 개발  >  PHP에서 IP 기반 점프를 구현하는 방법

PHP에서 IP 기반 점프를 구현하는 방법

藏色散人
藏色散人원래의
2020-08-31 10:54:342499검색

PHP는 IP 기반 점프 방법을 구현합니다. 먼저 현재 IP의 도시 문자열을 반환한 다음 IP 주소를 확인한 다음 IP 데이터 파일을 분해하여 마지막으로 바이너리 검색 방법을 사용합니다. 인덱스 레코드에서 일치하는 IP를 기록하고 해당 교체 작업을 수행합니다.

PHP에서 IP 기반 점프를 구현하는 방법

추천: "PHP 비디오 튜토리얼"

IP 및 점프를 기반으로 도시를 결정하는 PHP 코드

코드:

<?php
//返回当前IP的城市字符串
function convertip($ip) {
    //IP数据文件路径
    $dat_path = &#39;QQWry.Dat&#39;;
    //检查IP地址
    if(!preg_match("/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/", $ip)) {
        return &#39;IP Address Error&#39;;
    }
    //打开IP数据文件
    if(!$fd = @fopen($dat_path, &#39;rb&#39;)){
        return &#39;IP date file not exists or access denied&#39;;
    }
    //分解IP进行运算,得出整形数
    $ip = explode(&#39;.&#39;, $ip);
    $ipNum = $ip[0] * 16777216 + $ip[1] * 65536 + $ip[2] * 256 + $ip[3];
    //获取IP数据索引开始和结束位置
    $DataBegin = fread($fd, 4);
    $DataEnd = fread($fd, 4);
    $ipbegin = implode(&#39;&#39;, unpack(&#39;L&#39;, $DataBegin));
    if($ipbegin < 0) $ipbegin += pow(2, 32);
    $ipend = implode(&#39;&#39;, unpack(&#39;L&#39;, $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 &#39;System Error&#39;;
        }
        //提取出来的数据转换成长整形,如果数据是负数则加上2的32次幂
        $ip1num = implode(&#39;&#39;, unpack(&#39;L&#39;, $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 &#39;System Error&#39;;
        }
        $DataSeek = implode(&#39;&#39;, unpack(&#39;L&#39;, $DataSeek.chr(0)));
        fseek($fd, $DataSeek);
        $ipData2 = fread($fd, 4);
        if(strlen($ipData2) < 4) {
            fclose($fd);
            return &#39;System Error&#39;;
        }
        $ip2num = implode(&#39;&#39;, unpack(&#39;L&#39;, $ipData2));
        if($ip2num < 0) $ip2num += pow(2, 32);
        //没找到提示未知
        if($ip2num < $ipNum) {
            if($Middle == $BeginNum) {
                fclose($fd);
                return &#39;Unknown&#39;;
            }
            $BeginNum = $Middle;
        }
    }
    $ipFlag = fread($fd, 1);
    if($ipFlag == chr(1)) {
        $ipSeek = fread($fd, 3);
        if(strlen($ipSeek) < 3) {
            fclose($fd);
            return &#39;System Error&#39;;
        }
        $ipSeek = implode(&#39;&#39;, unpack(&#39;L&#39;, $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 &#39;System Error&#39;;
        }
        $ipFlag = fread($fd, 1);
        if($ipFlag == chr(2)) {
            $AddrSeek2 = fread($fd, 3);
            if(strlen($AddrSeek2) < 3) {
                fclose($fd);
                return &#39;System Error&#39;;
            }
            $AddrSeek2 = implode(&#39;&#39;, unpack(&#39;L&#39;, $AddrSeek2.chr(0)));
            fseek($fd, $AddrSeek2);
        } else {
            fseek($fd, -1, SEEK_CUR);
        }
        while(($char = fread($fd, 1)) != chr(0))
            $ipAddr2 .= $char;
        $AddrSeek = implode(&#39;&#39;, unpack(&#39;L&#39;, $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 &#39;System Error&#39;;
            }
            $AddrSeek2 = implode(&#39;&#39;, unpack(&#39;L&#39;, $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(&#39;/http/i&#39;, $ipAddr2)) {
        $ipAddr2 = &#39;&#39;;
    }
    $ipaddr = "$ipAddr1 $ipAddr2";
    $ipaddr = preg_replace(&#39;/CZ88.Net/is&#39;, &#39;&#39;, $ipaddr);
    $ipaddr = preg_replace(&#39;/^s*/is&#39;, &#39;&#39;, $ipaddr);
    $ipaddr = preg_replace(&#39;/s*$/is&#39;, &#39;&#39;, $ipaddr);
    if(preg_match(&#39;/http/i&#39;, $ipaddr) || $ipaddr == &#39;&#39;) {
        $ipaddr = &#39;Unknown&#39;;
    }
    return $ipaddr;
}
//查找字符串
function  findstr($str, $substr)
{
         $m = strlen($str);
        $n = strlen($substr );
        if ($m < $n) return false ;
        for ($i=0; $i <=($m-$n+1); $i ++){
                $sub = substr( $str, $i, $n);
                if ( strcmp($sub, $substr) ==  0)  return true;
        }
        return false ;
}
 
$xp_UserIp = ($_SERVER["HTTP_VIA"]) ? $_SERVER["HTTP_X_FORWARDED_FOR"] : $_SERVER["REMOTE_ADDR"];
$Clientip = ($xp_UserIp) ? $xp_UserIp : $_SERVER["REMOTE_ADDR"];
$ClientSity=convertip($Clientip);
if (findstr($ClientSity,"北京")){
    //out.print("beijing");
    Header("Location: http://www.qq.com");
}else{
    //out.print("false beijing");
    Header("Location: http://www.163.com");
}
?>

위 내용은 PHP에서 IP 기반 점프를 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.