Files
tools/.hta_slug/location-ip-to-location.php
2026-01-20 16:26:36 +05:30

84 lines
2.3 KiB
PHP

<?php
// ❌ No header() here
require_once __DIR__ . '/../.hta_lib/maxmind-db-reader/autoload.php';
use MaxMind\Db\Reader;
function respond($status, $data = null, $error = null)
{
echo json_encode([
'success' => $status,
'data' => $data,
'error' => $error
], JSON_PRETTY_PRINT);
exit;
}
if (!isset($_GET['ip']) || trim($_GET['ip']) === '') {
respond(false, null, 'IP parameter is required');
}
$ip = trim($_GET['ip']);
if (!filter_var($ip, FILTER_VALIDATE_IP)) {
respond(false, null, 'Invalid IP address');
}
try {
$cityReader = new Reader(__DIR__ . '/../.hta_lib/data/GeoLite2-City.mmdb');
$asnReader = new Reader(__DIR__ . '/../.hta_lib/data/GeoLite2-ASN.mmdb');
$cityData = $cityReader->get($ip);
$asnData = $asnReader->get($ip);
$cityReader->close();
$asnReader->close();
$response = [
'ip' => $ip,
'continent' => [
'name' => $cityData['continent']['names']['en'] ?? null,
'code' => $cityData['continent']['code'] ?? null
],
'country' => [
'name' => $cityData['country']['names']['en'] ?? null,
'code' => $cityData['country']['iso_code'] ?? null
],
'state' => [
'name' => $cityData['subdivisions'][0]['names']['en'] ?? null,
'code' => $cityData['subdivisions'][0]['iso_code'] ?? null
],
'city' => $cityData['city']['names']['en'] ?? null,
'timezone' => $cityData['location']['time_zone'] ?? null,
'location' => [
'latitude' => $cityData['location']['latitude'] ?? null,
'longitude' => $cityData['location']['longitude'] ?? null
],
'postal_code' => $cityData['postal']['code'] ?? null,
'asn' => [
'number' => $asnData['autonomous_system_number'] ?? null,
'org' => $asnData['autonomous_system_organization'] ?? null
],
];
$anycastASN = [15169, 13335, 36692];
$response['is_anycast'] = in_array($response['asn']['number'], $anycastASN);
$response['note'] = $response['is_anycast']
? 'Anycast IP detected. Location may vary.'
: 'IP-based location is approximate.';
respond(true, $response);
} catch (Exception $e) {
respond(false, null, $e->getMessage());
}