本文概述
- 与使用其余API相比, 此方法的优势
- 1.下载GeoLite2免费数据库
- 2.安装MaxMind GeoIP2 PHP API
- 3.从控制器检索有关用户IP的地理信息
这就是为什么还有其他选择的原因, 例如基于数据库的选择。 MaxMind提供的GeoLite2数据库是该方法最知名的免费替代方法之一。在本文中, 我们将向你展示如何使用Symfony项目中的GeoLite2数据库从访问者的IP中获取国家, 城市和地区。
与使用其余API相比, 此方法的优势 在你的服务器中本地拥有一个地理数据库的最明智的原因是, 你无需执行对任何第三方服务器的请求。相反, 你正在查询一个本地数据库, 该数据库的性能仅取决于你的服务器, 而不取决于连接或第三方服务的可用性。你附近有一个数据库来查询有关用户ip的信息, 这种情况再清楚不过了。
1.下载GeoLite2免费数据库 第一步, 你将需要项目中或在系统级别可访问的GeoLite二进制数据库。你可以从此处免费从官方的MaxMind GeoLite2下载数据库:
文章图片
在本教程中, 我们将使用数据库并将其包含在我们自己的项目中的symfony项目的/ private目录中(请注意, 该目录不存在, 因此需要创建, 你可以根据以下内容更改数据库的路径:你的需求), 我们将使用数据库的城市版本, 该数据库使我们能够获取本文中提到的信息, 尤其是访问者IP的城市, 国家和地区。数据库是使用tar压缩的, 因此你可以使用以下命令从命令行提取其内容:
tar -xzf GeoLite2-City_20180206.tar.gz
另外, 在Windows等其他操作系统中, 你也可以使用7Zip, Winrar或其他解压缩工具来提取其内容。现在你的项目中已有数据库, 目录结构应如下所示:
注意 如果有多个使用数据库的项目, 则可能要将数据库放置在所有项目都可以访问它的其他位置。就像本教程中一样, 我们只需要该项目中的数据库, 我们也将其放置在项目中。
文章图片
GeoLite2-City.mmdb文件大小约为63MB, 其中包含从用户IP推断出所需信息所需的所有信息。
2.安装MaxMind GeoIP2 PHP API 为了读取数据库, 你不需要托管在MySQL或其他数据库管理器中。数据库具有来自GeoIP的创建者的特殊格式, 即MaxMind DB。 MaxMind DB文件格式是一种数据库格式, 可以使用有效的二进制搜索树将IPv4和IPv6地址映射到数据记录。二进制数据库分为三个部分:
- 二进制搜索树。树的每个级别对应于IPv6地址的128位表示形式中的单个位。
- 数据部分。这些是针对特定IP地址返回给客户端的值, 例如” 美国” , “ 纽约” 或由多个字段组成的更复杂的地图类型。
- 数据库元数据。有关数据库本身的信息。
现在, 我们需要一种用于这种数据库格式的解析器。幸运的是, MaxMind团队为PHP编写了一个很棒的库, 它使与数据库的交互变得非常容易, 并且你仅需几行代码就可以检索有关用户IP的地理信息。我们正在谈论的是MaxMind GeoIP PHP Api, 该软件包为GeoIP2 Web服务和数据库提供了API。该API还可以与免费的GeoLite2数据库(我们正在使用的数据库)一起使用。你可以使用运行以下命令的composer将此软件包安装在Symfony项目中:
composer require geoip2/geoip2
有关此库的更多信息, 请访问Github上的官方存储库。安装软件包后, 你将可以在Symfony的控制器上使用其类。
3.从控制器检索有关用户IP的地理信息 现在你已经有了数据库和包装器, 可以从中读取信息, 你可以简单地继续从数据库中请求有关指定IP的信息。实现此目的的逻辑如下, 声明一个变量, 该变量包含GeoLite2-City数据库的绝对(本地)路径。这需要作为GeoIp2的Reader类的新实例的第一个参数提供, 你将使用该实例来查询有关IP的信息。最后, 从创建的实例中执行city方法, 该实例提供你要从中获取信息的IP作为第一个参数。显然, 你需要提供一个有效的IP, 否则读取器将引发异常, 显然, 你还需要做好准备, 以使数据库无法识别用户的IP, 因此在查询IP信息时需要捕获AddressNotFoundException。 :
<
?phpnamespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
// Include GeoIp2 Classesuse GeoIp2\Database\Reader;
use GeoIp2\Exception\AddressNotFoundException;
class DefaultController extends Controller{/*** @Route("/", name="homepage")*/public function indexAction(Request $request){// Declare the path to the GeoLite2-City.mmdb file (database)$GeoLiteDatabasePath = $this->
get('kernel')->
getRootDir() . '/../private/geolite2-city/GeoLite2-City.mmdb';
// Create an instance of the Reader of GeoIp2 and provide as first argument// the path to the database file$reader = new Reader($GeoLiteDatabasePath);
try{// if you are in the production environment you can retrieve the// user's IP with $request->
getClientIp()// Note that in a development environment 127.0.0.1 will// throw the AddressNotFoundException// In this example, use a fixed IP address in Minnesota$record = $reader->
city('128.101.101.101');
} catch (AddressNotFoundException $ex) {// Couldn't retrieve geo information from the given IPreturn new Response("It wasn't possible to retrieve information about the providen IP");
}return new JsonResponse($record);
}}
在具有给定IP的示例中, 你将在浏览器中获得以下输出的JSON响应:
{ "city": {"geoname_id": 5037649, "names": {"de": "Minneapolis", "en": "Minneapolis", "es": "Mineápolis", "fr": "Minneapolis", "ja": "ミネアポリス", "pt-BR": "Minneapolis", "ru": "Миннеаполис", "zh-CN": "明尼阿波利斯"} }, "continent": {"code": "NA", "geoname_id": 6255149, "names": {"de": "Nordamerika", "en": "North America", "es": "Norteamérica", "fr": "Amérique du Nord", "ja": "北アメリカ", "pt-BR": "América do Norte", "ru": "Северная Америка", "zh-CN": "北美洲"} }, "country": {"geoname_id": 6252001, "iso_code": "US", "names": {"de": "USA", "en": "United States", "es": "Estados Unidos", "fr": "états-Unis", "ja": "アメリカ合衆国", "pt-BR": "Estados Unidos", "ru": "США", "zh-CN": "美国"} }, "location": {"accuracy_radius": 5, "latitude": 44.9759, "longitude": -93.2166, "metro_code": 613, "time_zone": "America/Chicago" }, "postal": {"code": "55414" }, "registered_country": {"geoname_id": 6252001, "iso_code": "US", "names": {"de": "USA", "en": "United States", "es": "Estados Unidos", "fr": "états-Unis", "ja": "アメリカ合衆国", "pt-BR": "Estados Unidos", "ru": "США", "zh-CN": "美国"} }, "subdivisions": [{"geoname_id": 5037779, "iso_code": "MN", "names": {"en": "Minnesota", "es": "Minnesota", "fr": "Minnesota", "ja": "ミネソタ州", "pt-BR": "Minesota", "ru": "Миннесота", "zh-CN": "明尼苏达州"}} ], "traits": {"ip_address": "128.101.101.101" }}
请注意, $ record变量是stdClass对象, 因此没有getter方法。你可以从PHP中的对象检索属性, 如下所示:
print($record->
country->
isoCode . "\n");
// 'US'print($record->
country->
name . "\n");
// 'United States'print($record->
country->
names['zh-CN'] . "\n");
// '美国'print($record->
mostSpecificSubdivision->
name . "\n");
// 'Minnesota'print($record->
mostSpecificSubdivision->
isoCode . "\n");
// 'MN'print($record->
city->
name . "\n");
// 'Minneapolis'print($record->
postal->
code . "\n");
// '55455'print($record->
location->
latitude . "\n");
// 44.9733print($record->
location->
longitude . "\n");
// -93.2323
MaxMind不提供免费的GeoLite2数据库的官方支持。如果你对GeoLite2数据库或GeoIP2 API有疑问, 请参阅stackoverflow的GeoIP问题和解答。
【如何使用Symfony 3中的免费GeoLite数据库从访问者的IP中检测城市,国家和地区】编码愉快!
推荐阅读
- 如何在Twig中将日期时间对象格式化为ISO 8601
- 如何检查用户是否已经选中了Google Recaptcha复选框
- 感悟|Java后端学习体系(韩顺平)
- Aria2怎样下载百度云?Aria2下载百度云运用图文详细教程
- 360压缩如何加密?360压缩加密办法列表
- 雷电安卓模拟器程序多开图文程图文详细教程
- DiskGenius怎样用?DiskGenius运用图文详细教程
- 搜狗输入法空格符号怎样打?搜狗输入法空格符号输入办法_搜狗输入法
- 百度输入法怎样打cf空格?百度输入法空格输入办法_百度输入法