首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 根據 IP 獲取地理位置:從本地庫到第三方 API 的完整方案

     編輯:PHP 相關知識

第一步:獲取客戶端真實 IP

function getClientIP(): string {
    $headers = [
        'HTTP_CLIENT_IP',
        'HTTP_X_FORWARDED_FOR',
        'HTTP_X_REAL_IP',
        'REMOTE_ADDR'
    ];
    foreach ($headers as $header) {
        if (!empty($_SERVER[$header])) {
            $ipList = array_map('trim', explode(',', $_SERVER[$header]));
            foreach ($ipList as $ip) {
                if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
                    return $ip;
                }
            }
        }
    }
    return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
}

要點:優先信任代理頭,過濾私有/保留地址,防止 IP 偽造。

方案一:純真 IP 庫(QQWry.dat)離線查詢

優點:無網絡依賴、查詢極快、無頻率限制。缺點:需定期更新數據文件、記憶體佔用較大。

require_once 'IpLocation.class.php'; // 需自行下載實現類

$ipLoc = new IpLocation('/path/to/QQWry.dat');
$location = $ipLoc->getlocation(getClientIP());
// 返回格式:['country' => '中國', 'area' => '北京市 海淀區']

方案二:第三方 HTTP API(適合低頻、簡單項目)

1. 新浪 IP 查詢接口

function getLocationBySina(string $ip): ?array {
    $url = "https://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip={$ip}";
    $json = @file_get_contents($url);
    return $json ? json_decode($json, true) : null;
}
// 返回:['ret' => 1, 'country' => '中國', 'province' => '北京', 'city' => '北京', ...]

2. ip138 / ip168 等傳統接口(需解析 HTML)

function getLocationByIp138(string $ip): string {
    $url = "https://www.ip138.com/ips138.asp?ip={$ip}";
    $html = @file_get_contents($url);
    if (preg_match('/<ul class="ul1"><li>(.*?)<\/li>/i', $html, $m)) {
        return strip_tags($m[1]);
    }
    return '未知地區';
}

警示:免費接口穩定性差、有頻率限制、返回格式可能變更,生產環境建議付費 API。

方案三:現代付費 API 推薦(高可用、精準)

架構建議:緩存 + 降級

function getLocationCached(string $ip): array {
    $cacheKey = "ip_loc:{$ip}";
    // 1. 嘗試 Redis 緩存(TTL 30 天)
    if ($cached = Redis::get($cacheKey)) return json_decode($cached, true);

    // 2. 主查詢:付費 API
    $result = @getLocationByPaidAPI($ip);
    // 3. 降級:免費 API
    if (!$result) $result = @getLocationBySina($ip);
    // 4. 最後降級:離線庫
    if (!$result) $result = @getLocationByQQWry($ip);

    $result = $result ?: ['country' => '未知', 'province' => '', 'city' => ''];
    Redis::setex($cacheKey, 2592000, json_encode($result));
    return $result;
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
服務商特點免費額度
高德/百度/騰訊地圖 API精度高、支援經緯度、豐富 POI每日 1-3 萬次
ipapi.co / ipinfo.io國際化、RESTful、含 ASN/公司信息月 1-5 萬次
MaxMind GeoIP2企業級、離線庫+在線 API、精準到城市付費