通过 Maxmind GeoLite2 Free 获取用户城市的本地化名称

Posted

技术标签:

【中文标题】通过 Maxmind GeoLite2 Free 获取用户城市的本地化名称【英文标题】:Get a localized name of the users city via Maxmind GeoLite2 Free 【发布时间】:2014-01-10 10:11:12 【问题描述】:

我想显示用户城市的德语名称。 Maxmind Geoip 的免费版本是否可行? 我没有找到打开 GeoLite2-City.mmdb 或 GeoLiteCity.dat 以查看列出哪些城市的方法,以构建我自己的翻译服务。我怎样才能打开它们?

【问题讨论】:

数据库包括德国城市名称。您使用的是什么 API? 带有 .dat 文件的 php API 【参考方案1】:

以下是不使用 Composer 的方法。

在此处下载 zip DB-Reader: https://github.com/maxmind/MaxMind-DB-Reader-php 在此处下载数据文件(城市或国家/地区或两者):http://dev.maxmind.com/geoip/geoip2/geolite2/ 解压数据文件并将它们放在一个新目录foo。 在 DB-Reader 中,将 examples/benchmark.php 复制到 foo/benchmark.php。 在 DB-Reader 中,将 src/MaxMind/Db 复制到 foo/Db。 编辑foo/benchmark.php

变化:

require_once '../vendor/autoload.php';
use MaxMind\Db\Reader;
$reader = new Reader('GeoIP2-City.mmdb');

收件人:

require_once __DIR__ . '/' . 'Db/Reader.php';
require_once __DIR__ . '/' . 'Db/Reader/Decoder.php';
require_once __DIR__ . '/' . 'Db/Reader/InvalidDatabaseException.php';
require_once __DIR__ . '/' . 'Db/Reader/Metadata.php';
require_once __DIR__ . '/' . 'Db/Reader/Util.php';     // new 2014/09
use MaxMind\Db\Reader;
$mmdb= true ? 'GeoLite2-City.mmdb' : 'GeoLite2-Country.mmdb';
$reader = new Reader( __DIR__  . '/' . $mmdb );

您需要 PHP 5.3+。与使用 Composer 相比,您甚至可以节省一些代码和文件数量。 (删除了一些测试代码,以及整个 Guzzle 结构。)此外,它更清楚地说明了命名空间在 PHP 中如何作为类的良好替代品(当类仅用于命名空间时)。

您可以丢弃benchmark.php 的其余部分并开始使用$reader->get()

如果您确实想要进行基准测试,在大多数平台上,您需要修改 rand() 调用。试试这个:

变化:

$ip = long2ip(rand(0, pow(2, 32) -1));

收件人:

$n= (float)mt_rand(0, pow(2, 31) - 1);
if (mt_rand(0,1)) $n+= pow(2, 31);
$ip = long2ip($n);

或者只是用'.'连接四个mt_rand(0,255),这可能更容易!

....................... 编辑 2014/09 ......................

在上面添加了“Db/Reader/Util.php”。

MaxMind-DB-Reader-php 版本:1.0.0 (2014-09-22)

您的文件结构应如下所示:

./benchmark.php
./GeoLite2-City.mmdb
./GeoLite2-Country.mmdb
./Db/Reader.php
./Db/Reader/Decoder.php
./Db/Reader/InvalidDatabaseException.php
./Db/Reader/Metadata.php
./Db/Reader/Util.php

【讨论】:

Kitchin,很高兴找到您的帖子,其中包含有关如何在没有作曲家的情况下使用 GeoLite2 的说明。我按照您的指示设置了文件夹结构,并将 benchmark.php 中的代码更新为与您所说的完全相同...但是当我运行脚本时,屏幕上没有显示任何内容,并且我的服务器错误日志文件显示:PHP Fatal error : 在第 238 行的 /SERVERPATH/foo/Db/Reader.php 中找不到类“MaxMind\Db\Reader\Util”(*其中 SERVERPATH 是服务器根目录的完整路径)。关于为什么这对我不起作用的任何想法?任何帮助将不胜感激!谢谢! 太棒了,感谢 Kitchin 修复了我的错误。还有一个(愚蠢的)问题......我如何真正让它返回一个基于 IP 的国家?在 $reader = new Reader... 行之后,我有 $place = $reader->country('##.###.##.###'); (其中 # 是实际的 IP 地址编号)并且它不起作用。我尝试用“城市”替换“国家”,但这也不起作用......我确定它很简单,我只是不确定我需要使用哪些参数来返回国家/地区。谢谢! (为了跟进我的最后一条评论,错误日志中显示的错误是“PHP 致命错误:调用未定义的方法 MaxMind\Db\Reader::city() in >>) @Mark $t = $reader->get($ip); $country = $t['country']['iso_code'];。要查看 get() 返回的所有内容,print_r($t)。例如,$t['country']['names']['en']$t['city']['names']['en']【参考方案2】:

GeoIP Legacy 数据库不包含本地化名称,但 GeoIP2(或 GeoLite2)数据库包含。您可以按如下方式访问本地化名称:

<?php
require_once 'vendor/autoload.php';
use GeoIp2\Database\Reader;

$reader = new Reader('/usr/local/share/GeoIP/GeoLite2-City.mmdb');

$record = $reader->city('128.101.101.101');

print($record->country->names['de'] . "\n");

或者,如果您希望阅读器默认使用德语并在不可用时回退到英语,您可以在构造函数中设置语言:

<?php
require_once 'vendor/autoload.php';
use GeoIp2\Database\Reader;

$reader = new Reader('/usr/local/share/GeoIP/GeoLite2-City.mmdb', array('de', 'en'));

$record = $reader->city('128.101.101.101');

print($record->country->name . "\n");

【讨论】:

构造函数不接受回退数组,但它可以工作。你有没有作曲家的例子吗? 第二个例子适用于我来自 Composer 的最新版本。我修复了一个未封闭的报价。 就没有 Composer 的示例而言,尽管有可能,但最好还是使用一些 PSR-0 自动加载器。您还需要安装 MaxMind DB API。【参考方案3】:

如果您完全关心performance,我建议您使用 PHP 扩展 API。使用 PHP (C API) 扩展,您每秒可以获得超过 700 万次查询。

我在这里描述如何编译扩展,以及如何使用 PHP 中的 mmdb 数据库来获取本地化的城市名称:

Intro to Maxmind GeoLite2 with Kohana PHP

【讨论】:

以上是关于通过 Maxmind GeoLite2 Free 获取用户城市的本地化名称的主要内容,如果未能解决你的问题,请参考以下文章

将 MaxMind 的 GeoLite2 导入 MySQL

Maxmind GeoLite2 纯 javascript/html 示例

尝试安装 maxmind geolite2 数据库

maxmind GeoLite2-City accuracy_radius

如何在 MySQL 中创建数据库以导入 Maxmind GeoLite2 city csv

在 SQL Server 中查询 Maxmind GeoLite2 City Blocks csv 以获取 IPv6 和 IPv4 地址的 geoname_id