生在紅旗下長在春風裡,長期浸泡在河蟹社會裡面所以久而久之就有了一些河蟹的思維方式,正好有一段時間在做一個.NET 的網站訪問統計系統,順便想
著怎麼 「監視」 下每一個留言的博主們的所在地,於是就有了如今下圖所示的根據獲取到的留言者的 IP 地址得到留言者所在的地區,當然並沒有河蟹社會監視人民
群眾的意思,純屬瞭解一下各位博主所在的真實地點,萬一是個美女博主不就可以讓我有線索可循。

PHP,IP地址轉換

想要把 IPv4 地址轉為真實的地址,肯定要參考 IP 資料庫,商業的 IP 資料庫儲存在關係型資料庫中,查詢和使用都非常方便,但是成本不是個人和小公
司願意承受的,所以簡單應用的思路就是利用一些免費的 IP 資料庫或者一些大網站提供的查詢 API,他們的資料量足夠我們使用了。

1. 利用純真 IP 資料庫

利用本地的 QQWry.Dat 檔案 (搜尋下載一個 QQWry.Dat
檔案放到你的 WordPress 主題根目錄下),優點是查詢速度非常快,缺點是資料庫檔案要放在自己的空間內並且要偶爾更新資料庫。時間關係廢話不多說,
下面是使用這個檔案的函式,如果是在 WordPress 裡面使用這個功能,把下面的程式碼寫入主題下面的 functions.php 裡面,然後在
comments-list 的輸出<?php echo convertip(get_comment_author_ip());
?> 即可。僅管理員可見話,則呼叫程式碼<?php if ( is_user_logged_in() ) echo convertip(get_comment_author_ip()); ?> 即可如果是其他程式引用,輸入一個有效的 IPv4 地址就可以得到一個真實的地址。

以下為引用的內容:

function convertip($ip) {
    $dat_path = TEMPLATEPATH.'/QQWry.Dat';
    if(!$fd = @fopen($dat_path, 'rb')){
        return 'IP date file not exists or access denied';
    }
    $ip = explode('.', $ip);
    $ipNum = $ip[0] * 16777216 + $ip[1] * 65536 + $ip[2] * 256 + $ip[3];
    $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;
    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';
    }
    $ipaddr = iconv('gbk', 'utf-8//IGNORE', $ipaddr);
    if( $ipaddr != '  ' )
        return $ipaddr;
    else
        $ipaddr = '地址未知!火星來客?';
        return $ipaddr;
}

文章來源:http://www.feiyan.info/408.html  轉載請註明出處連結

編輯備註:為了便於閱讀,文章略有調整。