「PHP」カテゴリーのロゴ

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

そもそもGeoIP2とは?

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

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

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

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

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

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

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

$ 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!

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

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アドレスによっては取得できない場合もある模様。やはり無料版だと有料版に比べ正確性に欠けるっぽい。