GeoIP 获取用户地理位置信息

首先感谢本文内容中每一个网页的作者
torann/geoip 提供了三种根据 IP 获取位置信息的服务:
ipapi —— 默认的方式,利用了 http://ip-api.com/ 的接口来获取位置信息;
maxmind_database —— 由 www.maxmind.com 提供的开源数据,需要下载数据到本地;
maxmind_api —— 利用 www.maxmind.com 提供的接口获取位置信息,需要付费的,本文不作讲解;
参考网站:
教程:[扩展推荐] geoip 获取 IP 地理信息
015. 通过 IP 获取到对应的地理位置信息——torann/geoip

ipapi —— 默认的方式

进入项目根目录,使用 composer 安装
1,执行如下命令: composer require torann/geoip
如果安装失败,原因 laravel 版本不同对应安装的版本也不同,可以到这个网址查看对应的版本
https://packagist.org/packages/torann/geoi...
我的是5.4版本的,就使用下面这个命令: composer require torann/geoip:v1.0.9
安装成功后 verdor 目录下就会多一个 torann 文件夹

2, 修改 config/app.php 文件,
在 providers 数组内追加如下内容:Torann\GeoIP\GeoIPServiceProvider::class,
在 aliases 数组内追加如下内容:’GeoIP’ => Torann\GeoIP\GeoIP::class,

3,生成配置文件,执行如下命令:php artisan vendor:publish
成功后,config目录下,就会出现 geoip.php 文件,
如果想用修改为中文显示,可以将 ipapi 里的 lang 修改为 zh-CN

4,更新 IP 地址库,执行如下命令:php artisan geoip:update
成功后,storage/app 目录下就会多一个 continents.json 文件
可以测试下:
$location = GeoIP::getLocation()->toArray();
var_dump($location);exit;
可以将ip详细信息打印出来,就成功了

使用 maxmind_database 的方式

上文中我们使用了默认的方式 ipapi,也就是请求了 http://ip-api.com/ 的接口,
那么如果处于某些原因,无法请求到接口,那么就可以使用 maxmind_database 的方式,将数据同步至本地,进行本地查询

1,要使用 maxmind_database 需要先安装 geoip2/geoip2 这个扩展包,官网地址:https://packagist.org/packages/geoip2/geoi...
执行命令安装:composer require geoip2/geoip2
执行成功后,vendor 目录下就会多3个文件夹 geoip2 和 maxmind-db 和 maxmind

2,安装成功后,修改一下配置文件config/geoip.php,
将使用的 service=’ipapi’ 修改为 service=’maxmind_database’,
同时修改使用的语言为 zh-CN,关闭 cache 功能 ‘cache’ => ‘none’

3,直接调用 geoip:update 命令可以将数据信息同步至本地:
php artisan geoip:update
成功后,数据文件下载到了 storage/app/geoip.mmdb 中

假如遇到异常无法更新数据库文件
Updating…
In MaxMindDatabase.php line 74:
get_headers(): php_network_getaddresses: getaddrinfo failed: Name or service not known
原因是从2019年12月30日开始,将要求GeoLite2数据库的用户注册一个MaxMind帐户并获取许可证密钥,以便下载GeoLite2数据库,那么可以注册一个账号然后就可以免费下载了。
注册地址:https://www.maxmind.com/en/geolite2/signup
注册成功后,可以翻译这个页面的内容,按照说明进行操作 https://dev.maxmind.com/geoip/geoipupdate/...
这是我的操作的步骤:
1,登录进来点击头像里面的 MY ACCOUNT,找到 Services 点击 My License Key ,打开页面后 点击Generate new license key,然后按照要求生成你的 许可证密钥 ,注意一定要在生成后立即复制保存好。
2,修改你的 config/geoip.php 配置文件,把 maxmind_database 里的 update_url 地址替换为
https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=这里写你的许可证密钥&suffix=tar.gz'
3,再次执行 php artisan geoip:update 即可成功更新
注意,假如更新成功后,测试的时候报
geoip.ERROR: MaxMind\Db\Reader\InvalidDatabaseException:
The MaxMind DB file’s search tree is corrupt in /test/vendor/maxmind-db/reader/src/MaxMind/Db/Reader.php:246
可能是更新的时候把数据文件解压失败了,破坏了数据文件,此时可以修改vendor\torann\geoip\src\Services\MaxMindDatabase.php
里的update 方法,修改为

/**
     * Update function for service.
     *
     * @return string
     * @throws Exception
     */
    public function update()
    {
        if ($this->config('database_path', false) === false) {
            throw new Exception('Database path not set in config file.');
        }

        $this->withTemporaryDirectory(function ($directory) {
            $tarFile = sprintf('%s/maxmind.tar.gz', $directory);

            file_put_contents($tarFile, fopen($this->config('update_url'), 'r'));

            $archive = new PharData($tarFile);

            $file = $this->findDatabaseFile($archive);

            $relativePath = "{$archive->getFilename()}/{$file->getFilename()}";

            $archive->extractTo($directory, $relativePath);

            file_put_contents($this->config('database_path'), fopen("{$directory}/{$relativePath}", 'r'));
        });

        return "Database file ({$this->config('database_path')}) updated.";
    }

    /**
     * Provide a temporary directory to perform operations in and and ensure
     * it is removed afterwards.
     *
     * @param  callable  $callback
     * @return void
     */
    protected function withTemporaryDirectory(callable $callback)
    {
        $directory = tempnam(sys_get_temp_dir(), 'maxmind');

        if (file_exists($directory)) {
            unlink($directory);
        }

        mkdir($directory);

        try {
            $callback($directory);
        } finally {
            $this->deleteDirectory($directory);
        }
    }

    /**
     * Recursively search the given archive to find the .mmdb file.
     *
     * @param  \PharData  $archive
     * @return mixed
     * @throws \Exception
     */
    protected function findDatabaseFile($archive)
    {
        foreach ($archive as $file) {
            if ($file->isDir()) {
                return $this->findDatabaseFile(new PharData($file->getPathName()));
            }

            if (pathinfo($file, PATHINFO_EXTENSION) === 'mmdb') {
                return $file;
            }
        }

        throw new Exception('Database file could not be found within archive.');
    }

    /**
     * Recursively delete the given directory.
     *
     * @param  string  $directory
     * @return mixed
     */
    protected function deleteDirectory(string $directory)
    {
        if (!file_exists($directory)) {
            return true;
        }

        if (!is_dir($directory)) {
            return unlink($directory);
        }

        foreach (scandir($directory) as $item) {
            if ($item == '.' || $item == '..') {
                continue;
            }

            if (!$this->deleteDirectory($directory . DIRECTORY_SEPARATOR . $item)) {
                return false;
            }
        }

        return rmdir($directory);
    }

4,再次执行 php artisan geoip:update 成功更新,测试也正常
5,这个数据文件是每周二更新的,所以可以写一个定时任务每周执行这个update方法更新数据文件

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!