PHP實現用IP搜尋國家地區,利用GeoLite2資料

簡介

透過此程式,能將訪客的IP搜尋GeoLite資料庫,可以搜尋出國家地區位置。

流程

  1. 建立GeoLite的資料庫
  2. 將GeoLite的cvs檔轉程sql
  3. 利用php將訪客的IP,去搜尋資料庫的資料

GeoLite2資料下載:https://dev.maxmind.com/geoip/geoip2/geolite2/
這裡我提供已經轉換好的sql資料(提供練習,所以資料不一定是最新的)

點我下載

問題與解決方法

問題一

用訪客的IP搜尋資料庫的話,不會搜尋到任何值,因為Geolite給的資料是給網段位置。
解決方法:

利用ip2long轉換ipv4,並判斷這個值位於哪個ip範圍的網段

問題二

分離IPV4的網段與遮罩掩碼

解決方法:

利用explode(分割位置,欲分割的字串)
例如:explode('/','192.168.2.5/24')

完整程式碼

<?php
$My_IP = $_SERVER["REMOTE_ADDR"];
$IP_ID = "";
$Count_Remote = ip2long($My_IP);
class IP_INFO{
    var $Conutry_Name = "";
    var $IP = "";
}
$INFO = new IP_INFO;

function Get_First_Three_IP($Input){ //目標取出Ip的前三段像192.168.1.10,只取192.168.1
    $Divid_IP = explode('.',$Input);
    $Combine_IP = $Divid_IP[0].".".$Divid_IP[1].".".$Divid_IP[2];
    return $Combine_IP;
}
function Show_Private_Context(){
    echo "您的IP為Private IP"."<br>".$GLOBALS['My_IP'];
}
/////////////////////////////////////////////////////////////////////連結資料庫設定
$host = "localhost";
$user = "root";
$password = "daljaihp";
$database = "ip_data";
$Link = new mysqli($host, $user, $password, $database);
if(mysqli_connect_error()){
    echo mysqli_connect_error();
}
/////////////////////////////////////////////////////////////////////
//判斷是否在private ip範圍內
if (ip2long("10.0.0.0")<$Count_Remote && $Count_Remote < ip2long("10.255.255.255")){Show_Private_Context();}
elseif (ip2long("172.16.0.0")<$Count_Remote && $Count_Remote < ip2long("172.31.255.255")){Show_Private_Context();}
elseif (ip2long("192.168.0.0")<$Count_Remote && $Count_Remote < ip2long("192.168.255.255")){Show_Private_Context();}
elseif (ip2long("127.0.0.0")<$Count_Remote && $Count_Remote < ip2long("127.0.0.255")){Show_Private_Context();}
elseif ($My_IP = "localhost"){Show_Private_Context();}
//進入尋找public ip資料的判斷
else
{
    $SQL_Target_IP = Get_First_Three_IP($My_IP);
    $Search_IP_Range = "SELECT * FROM `country_blocks_ipv4` WHERE `network` LIKE '%$SQL_Target_IP%'"; //從SQL搜尋近似資料
    $result = $Link->query($Search_IP_Range);
    if ($result->num_rows > 0) { //判斷是否超過1條數據
        while ($row = $result->fetch_assoc()) // 輸出數據
        {
            $Split_IP = explode('/',$row["network"]); //分割IP字串,並放在陣列里
            $Start_IP = ip2long($Split_IP[0]); //IP起始位置
            $IP_Subnet_Mask = (int)$Split_IP[1]; //遮罩掩碼
            $End_IP = $Start_IP + pow(2,(32 - $IP_Subnet_Mask)-1); //計算網段主機數量範圍
            if ($Start_IP < $Count_Remote && $Count_Remote < $End_IP){ //比較多組搜尋資料,只需要找到ip範圍內的
                $IP_ID = $row["geoname_id"];
            }
        }
        $Seach_Country = "SELECT * FROM `country_loaction` WHERE `geoname_id`='$IP_ID'"; //從SQL搜尋IP ID
        $result = $Link->query($Seach_Country);
        if ($result->num_rows > 0) { // 判斷是否超過1條數據
            while ($row = $result->fetch_assoc()) // 輸出數據
            {
                echo "你的IP地址為".$My_IP.":".$row["country_name"]; //取出國家資料
            }
        }
        else {echo "未知的地區位置";}
    }
    else {echo "未知的地區位置";}
}
$Link -> close();
?>
Last modification:November 30th, 2018 at 05:25 pm