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

PHP 淘寶/新浪 IP 地址歸屬地查詢類封裝 (TaobaoIPQuery2)

     編輯:PHP 相關知識

TaobaoIPQuery2 完整實現

<?php
class TaobaoIPQuery2 {
    private const API_URL = 'https://ip.taobao.com/service/getIpInfo.php';
    private const TIMEOUT = 3.0;
    
    private string $ip;
    private ?object $data = null;
    
    public function __construct(string $ip) {
        if (empty($ip)) throw new InvalidArgumentException('IP address required');
        $this->ip = $this->normalizeIp($ip);
        $this->fetch();
    }
    
    private function normalizeIp(string $ip): string {
        // 取第一個非 unknown IP (代理鏈場景)
        $ips = array_map('trim', explode(',', $ip));
        foreach ($ips as $candidate) {
            if ($candidate !== 'unknown' && filter_var($candidate, FILTER_VALIDATE_IP)) {
                return $candidate;
            }
        }
        return $ips[0] ?? '0.0.0.0';
    }
    
    private function fetch(): void {
        $url = self::API_URL . '?ip=' . urlencode($this->ip);
        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT        => self::TIMEOUT,
            CURLOPT_SSL_VERIFYPEER => false,
        ]);
        $resp = curl_exec($ch);
        $errno = curl_errno($ch);
        curl_close($ch);
        
        if ($errno) throw new RuntimeException("cURL error: " . curl_error($ch));
        if (!$resp) throw new RuntimeException('Empty response');
        
        $json = json_decode($resp);
        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new RuntimeException('JSON error: ' . json_last_error_msg());
        }
        if (!isset($json->code) || $json->code !== 0) {
            throw new RuntimeException('API error: ' . ($json->msg ?? 'Unknown'));
        }
        $this->data = $json->data;
    }
    
    public function getCountry(): string { return $this->data->country ?? ''; }
    public function getRegion(): string  { return $this->data->region ?? ''; }
    public function getCity(): string    { return $this->data->city ?? ''; }
    public function getIsp(): string     { return $this->data->isp ?? ''; }
    public function getArea(): string    { return $this->data->area ?? ''; }
    public function getIp(): string      { return $this->data->ip ?? $this->ip; }
    public function toArray(): array     { return (array)$this->data; }
}

// 使用
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';
$query = new TaobaoIPQuery2($ip);
echo "{$query->getCountry()} {$query->getRegion()} {$query->getCity()} {$query->getIsp()}";

新浪 IP 接口替代

class SinaIPQuery {
    private const API_URL = 'https://ipapi.sinaapp.com/';
    
    public static function query(string $ip): ?array {
        $url = self::API_URL . '?ip=' . urlencode($ip) . '&type=json';
        $json = @file_get_contents($url);
        if (!$json) return null;
        $data = json_decode($json, true);
        return $data['ret'] === 1 ? $data['data'] : null;
    }
}

// 返回格式: ['country'=>'中国', 'province'=>'北京', 'city'=>'北京', 'isp'=>'联通', ...]

生產環境架構建議

層級方案優點
L1 緩存Redis 緩存查詢結果 (TTL 30 天)毫秒級響應、減輕外部 API 壓力
L2 異步消息隊列異步查詢,不阻塞主流程高併發下穩定
L3 降級多源輪詢 (淘寶→新浪→ip2location 本地庫)單點故障不影響業務
L4 離線MaxMind GeoIP2 / IP2Location 本地數據庫零網絡延遲、無外部依賴、適合超高頻

Composer 現代替代

composer require geoip2/geoip2:~2.0
// 使用 MaxMind 官方庫
$reader = new GeoIp2\Database\Reader('/path/to/GeoLite2-City.mmdb');
$record = $reader->city($ip);
echo $record->country->name; // China
echo $record->city->name;    // Beijing
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved