You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PHP中获取域名访客的IP及完整地理位置信息

How to Get Full Geolocation Details (City, State, Region) from Visitor IPs

Hey there! Your current code only pulls in the visitor's IP and country because it’s likely relying on a basic IP-to-country mapping. To get city, state/region, and more granular location data, you’ll need a more robust geolocation data source. Let’s break down two reliable approaches:

Option 1: Use a Local Geolocation Database (MaxMind GeoLite2)

This is my go-to for performance (no external API calls) and reliability. Here’s how to set it up:

  1. Grab the GeoLite2 City Database
    Create a free account on MaxMind’s platform, then download the GeoLite2 City database (it comes as a .mmdb file). Store this file in a secure, accessible directory on your server.

  2. Install the MaxMind PHP Library
    Use Composer to add the official library to your project:

    composer require maxmind/geoip2
    
  3. Update Your Code
    Replace your existing ip_visitor_country() function with a comprehensive version that fetches all the details you need. Here’s a full working example:

    <?php
    require 'vendor/autoload.php'; // Load Composer dependencies
    
    use GeoIp2\Database\Reader;
    
    function get_visitor_geolocation() {
        // Step 1: Get the real visitor IP (handle proxies)
        $client = @$_SERVER['HTTP_CLIENT_IP'];
        $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
        $remote = $_SERVER['REMOTE_ADDR'];
        $ip = $remote;
    
        if(filter_var($client, FILTER_VALIDATE_IP)){
            $ip = $client;
        } elseif(filter_var($forward, FILTER_VALIDATE_IP)){
            $ip = $forward;
        }
    
        // Initialize default values
        $geolocation = [
            'ip' => $ip,
            'country' => 'Unknown',
            'region' => 'Unknown',
            'city' => 'Unknown',
            'state_code' => 'Unknown'
        ];
    
        try {
            // Path to your GeoLite2 City database file
            $reader = new Reader('/path/to/GeoLite2-City.mmdb');
            $record = $reader->city($ip);
    
            // Populate geolocation data
            $geolocation['country'] = $record->country->name ?? 'Unknown';
            $geolocation['region'] = $record->mostSpecificSubdivision->name ?? 'Unknown';
            $geolocation['state_code'] = $record->mostSpecificSubdivision->isoCode ?? 'Unknown'; // e.g., CA for California
            $geolocation['city'] = $record->city->name ?? 'Unknown';
    
            $reader->close();
        } catch (\Exception $e) {
            // Log errors (e.g., invalid IP, missing database)
            error_log("Geolocation lookup failed: " . $e->getMessage());
        }
    
        return $geolocation;
    }
    
    // Usage example
    $visitorData = get_visitor_geolocation();
    echo "IP: " . $visitorData['ip'] . "<br>";
    echo "Country: " . $visitorData['country'] . "<br>";
    echo "Region/State: " . $visitorData['region'] . "<br>";
    echo "State Code: " . $visitorData['state_code'] . "<br>";
    echo "City: " . $visitorData['city'] . "<br>";
    ?>
    

Option 2: Use a Third-Party Geolocation API

If you don’t want to manage a local database, you can use an API like IPinfo or IP2Location. These services return JSON data with all the details you need. Here’s a quick example using IPinfo (free tier available):

<?php
function get_visitor_geolocation_via_api() {
       // Get real visitor IP
       $client = @$_SERVER['HTTP_CLIENT_IP'];
       $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
       $remote = $_SERVER['REMOTE_ADDR'];
       $ip = $remote;

       if(filter_var($client, FILTER_VALIDATE_IP)){
           $ip = $client;
       } elseif(filter_var($forward, FILTER_VALIDATE_IP)){
           $ip = $forward;
       }

       $geolocation = [
           'ip' => $ip,
           'country' => 'Unknown',
           'region' => 'Unknown',
           'city' => 'Unknown',
           'state_code' => 'Unknown'
       ];

       // Call the API (replace with your preferred service's endpoint)
       $apiUrl = "https://ipinfo.io/{$ip}/json";
       $response = file_get_contents($apiUrl);

       if($response) {
           $data = json_decode($response, true);
           $geolocation['country'] = $data['country'] ?? 'Unknown';
           $geolocation['region'] = $data['region'] ?? 'Unknown';
           $geolocation['city'] = $data['city'] ?? 'Unknown';
           $geolocation['state_code'] = $data['region'] ?? 'Unknown'; // IPinfo uses 'region' for state/province
       }

       return $geolocation;
   }

// Usage example
$visitorData = get_visitor_geolocation_via_api();
print_r($visitorData);
?>

Key Considerations

  • Proxy Safety: Your existing IP detection logic is a solid start, but be aware that HTTP_X_FORWARDED_FOR can be spoofed. For production, validate against trusted proxies if your server is behind a CDN or load balancer.
  • Privacy Compliance: Make sure you’re following regulations like GDPR or CCPA—inform visitors you’re collecting geolocation data and give them opt-out options if required.
  • Data Freshness: If using the local MaxMind database, set up a cron job to update it weekly (MaxMind releases regular updates) to keep your location data accurate.

内容的提问来源于stack exchange,提问作者Sagu K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:28:36