通过 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 纯 javascript/html 示例
maxmind GeoLite2-City accuracy_radius
如何在 MySQL 中创建数据库以导入 Maxmind GeoLite2 city csv
在 SQL Server 中查询 Maxmind GeoLite2 City Blocks csv 以获取 IPv6 和 IPv4 地址的 geoname_id