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 偽造。
優點:無網絡依賴、查詢極快、無頻率限制。缺點:需定期更新數據文件、記憶體佔用較大。
require_once 'IpLocation.class.php'; // 需自行下載實現類
$ipLoc = new IpLocation('/path/to/QQWry.dat');
$location = $ipLoc->getlocation(getClientIP());
// 返回格式:['country' => '中國', 'area' => '北京市 海淀區']
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' => '北京', ...]
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 | 精度高、支援經緯度、豐富 POI | 每日 1-3 萬次 |
| ipapi.co / ipinfo.io | 國際化、RESTful、含 ASN/公司信息 | 月 1-5 萬次 |
| MaxMind GeoIP2 | 企業級、離線庫+在線 API、精準到城市 | 付費 |