php7.2的环境:

yum install epel-release -y && rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm \
&& yum -y remove php* \
&& yum -y install php72w php72w-cli php72w-fpm php72w-common php72w-devel php72w-embedded php72w-gd php72w-mbstring php72w-mysqlnd php72w-opcache php72w-pdo php72w-xml php72w-devel php72w-pear \
&& yum install gcc make autoconf libc-dev pkg-config openssl openssl-devl glibc-headers gcc-c++ gcc-g77 libyaml-devel libssh2 libssh2-devel -y 
 
sh -c '/bin/echo -e "\n" | sh pecl install ssh2-1.0' && sh -c '/bin/echo "extension=ssh2.so" > /etc/php.d/ssh2.ini' \
&& sh -c '/bin/echo -e "\n" | sh pecl install yaml' && sh -c '/bin/echo "extension=yaml.so" > /etc/php.d/yaml.ini' \
&& sh -c '/bin/echo -e "\nyes\nyes\nyes\nyes" | sh pecl install swoole' && sh -c '/bin/echo "extension=swoole.so" > /etc/php.d/swoole.ini'

下载GeoLite2-City.mmdb:

https://dev.maxmind.com/geoip/geolite2-free-geolocation-data

下载读取GeoLite2-City.mmdb的php代码:

https://github.com/maxmind/MaxMind-DB-Reader-php

读取:

<?php
require_once 'vendor/autoload.php';

use MaxMind\Db\Reader;

$ipAddress = '24.24.24.24';
$databaseFile = 'GeoIP2-City.mmdb';

$reader = new Reader($databaseFile);

// get returns just the record for the IP address
print_r($reader->get($ipAddress));

// getWithPrefixLen returns an array containing the record and the
// associated prefix length for that record.
print_r($reader->getWithPrefixLen($ipAddress));

$reader->close();

web api:

<?php
#require_once 'vendor/autoload.php';
require_once 'MaxMind-DB-Reader-php/autoload.php';

use MaxMind\Db\Reader;

// ini_set('display_errors','1');
ini_set('max_execution_time', 3);

// $ipAddress = '';
$databaseFile = 'GeoLite2-City.mmdb';
$reader = new Reader($databaseFile);

// echo '<pre>';
// get returns just the record for the IP address
// print_r($reader->get($ipAddress));

$ips = explode(',', rtrim($_GET['ip'], ','));

foreach($ips as $val)
{
	if(filter_var($val, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)){
		$ip = $reader->get($val);
		echo $val.': '.$ip['continent']['names']['zh-CN'].$ip['country']['names']['zh-CN'].$ip['subdivisions'][0]['names']['zh-CN'].$ip['city']['names']['zh-CN']."\n";
	}else{
		echo $val.": invalid value\n";
	}
}

// getWithPrefixLen returns an array containing the record and the
// associated prefix length for that record.
// print_r($reader->getWithPrefixLen($ipAddress));

$reader->close();

golang:命令的方式

package main

import (
    "fmt"
    "log"
    "net"
    "os"

    "github.com/oschwald/geoip2-golang"
)

func main() {
    db, err := geoip2.Open("/usr/local/bin/GeoLite2-City.mmdb") // /usr/local/bin/
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    for i, v := range os.Args {
        if i == 0 {
            continue
        }
        ip := net.ParseIP(v)
        record, err := db.City(ip)
        if err != nil {
            log.Fatal(err)
        }
        if len(record.Subdivisions) > 0 {
            fmt.Println(v + ": " + record.Continent.Names["zh-CN"] + record.Subdivisions[0].Names["zh-CN"] + record.Country.Names["zh-CN"] + record.City.Names["zh-CN"])
        }
    }
}