【PHP】GeoIP2でIPアドレスから国・地域名を取得する

そもそもGeoIP2とは?

GeoIP2はMaxMind社が提供するパッケージ。IPアドレスから国や地名、緯度・経度をはじめとした様々な情報を取得できる。

無料で使用できるが有償版と比べるとスペックでは劣り、更新頻度も低め。加えて商用で使用する際はライセンスの表記なども必要になる。

ちなみにAPIを利用する方法もあるが、今回はDBファイルをダウンロードする方法で試してみる。

IPアドレスから国・地域名を取得する方法

大まかな流れは以下の通り。

  1. GeoIP2のパッケージをインストールする
  2. データベースファイルをダウンロードする
  3. データベースを読み込む
  4. IPアドレスから地域情報を取得する

1. GeoIP2のパッケージをインストールする

Terminal window
$ composer require geoip2/geoip2:~2.4

まずはcomposerを利用してGeoIP2のパッケージをインストール。

2 package suggestions were added by new dependencies, use `composer suggest` to see details.
Generating autoload files
1 package you are using is looking for funding.
Use the `composer fund` command to find out more!

上のようにメッセージが出力されればインストール完了。

Terminal window
ls -F vendor
autoload.php composer/ geoip2/ maxmind/ maxmind-db/

そしてvendorディレクトリ下がこのようになっていればOK。

2. データベースファイルをダウンロードする

次に、公式サイトからGeoLite2のDBファイルをダウンロードしていく。

2-1. アカウントを作成する

「Sign Up for GeoLite2」をクリックしアカウントを作成する

「Sign Up for GeoLite2」をクリックしアカウントを作成開始。

必要事項を記入する

必要事項を記入する。画像の通り、メアドまで入力すればOK。

パスワードを設定しログインする

すると入力したアドレス宛にメールが届くので、そこのURLからパスワードを設定しログインする。

ちなみに今回はお試しで利用するだけなので不要だが、商用で利用する際などにはライセンスキーの取得が必要になってくる。

2-2. データベースファイルをダウンロードする

「GeoLite2 Free Geolocation Data」をクリックする

まずはダウンロードページにアクセスしたいので、サイトのフッターメニューから「GeoLite2 Free Geolocation Data」をクリック。

「Download Files」をクリックする

既視感のある画面に来たら、今度はその中の「Download Files」をクリック。

zipファイルをダウンロードする

するとダウンロードページに遷移するので、「GeoLite2-City.mmdb」「GeoLite2-Country.mmdb」のどちらかのzipファイルをダウンロード。今回は国名を取得したいので後者を選択する。

2-3. 解凍し配置する

ダウンロードしたzipファイルを解凍し、mmdb拡張子のDBファイルを適当なパスに配置してあげる。

3. データベースを読み込む

require 'vendor/autoload.php';
use GeoIp2\Database\Reader;
$reader = new Reader('GeoLite2-Country.mmdb');

vendor下のautoload.phpを読み込み、Readerクラスのインスタンスを作成する。

4. IPアドレスから地域情報を取得する

require 'vendor/autoload.php';
use GeoIp2\Database\Reader;
$reader = new Reader('{PATH}/GeoLite2-Country.mmdb');
$ipAddress = '198.143.164.252'; // ja.wordpress.orgのIPアドレス
var_dump($reader->country($ipAddress));

IPアドレスを引数に指定してcityメソッドを呼んでみる。

object(GeoIp2\Model\City)#4 (12) {
["city":protected]=>
object(GeoIp2\Record\City)#13 (3) {
["validAttributes":protected]=>
array(3) {
[0]=>
string(10) "confidence"
[1]=>
string(9) "geonameId"
[2]=>
string(5) "names"
}
["locales":"GeoIp2\Record\AbstractPlaceRecord":private]=>
array(1) {
[0]=>
string(2) "en"
}
["record":"GeoIp2\Record\AbstractRecord":private]=>
array(0) {
}
}
["location":protected]=>
object(GeoIp2\Record\Location)#14 (2) {
["validAttributes":protected]=>
array(9) {
[0]=>
string(13) "averageIncome"
[1]=>
string(14) "accuracyRadius"
[2]=>
string(8) "latitude"
[3]=>
string(9) "longitude"
[4]=>
string(9) "metroCode"
[5]=>
string(17) "populationDensity"
[6]=>
string(10) "postalCode"
[7]=>
string(16) "postalConfidence"
[8]=>
string(8) "timeZone"
}
(以下略)

上のようにオブジェクトの中身がずらっと出力された。国名なども含まれてる。

require 'vendor/autoload.php';
use GeoIp2\Database\Reader;
$reader = new Reader('{PATH}/GeoLite2-Country.mmdb');
$ipAddress = '198.143.164.252'; // ja.wordpress.orgのIPアドレス
var_dump($reader->country($ipAddress)->country->names['ja']);

てことでプロパティ名を指定して日本語で国名を出力してみる。

string(21) "アメリカ合衆国"

無事、国名が取得できた。

色々試してみたところ、IPアドレスによっては取得できない場合もある模様。やはり無料版だと有料版に比べ正確性に欠けるっぽい。