conocode
このコード
How to

PHPでユーザーのIP アドレスから地域情報を取得する

PHPでユーザがアクセスしている場所を特定したいんですけど
正確な位置はわからないけどおおよその地域は特定できるよ

ユーザの位置を知りたいときってサービスによってはけっこうあります。

最近はHTML5の Geolocation API を使えば正確な位置まで取得できる場合もありますが、ユーザが同意しなかったり、そこまで正確な位置情報が不要だったりした場合はIPアドレスから地域を割り出す方法がまだまだ現役です。

今回はサーバ側のPHPでアクセスしてきたユーザのIPアドレスから地域を割り出す手順をお伝えします。

環境は CentOS 7 , PHP 7.1 という前提での手順となりますのでご了承ください。

どんなライブラリを使うか

ライブラリ(サービス)は GeoIP を使います。

インストール・環境設定

まず yum で必要なモジュールをインストールします

yum install re2c geoip geoip-devel

PHP用のライブラリのインストールも必要なので php-pear をまずインストール

yum install –enablerepo=remi,remi-php71 php-pear

pear がインストールできたら PHP用のGeoIP をインストール

pecl install -f geoip-1.1.1

ライブラリがインストールできたらPHPがライブラリを読み込むように設定します。

/etc/php.ini ファイルに

を追加

Webサーバを再起動します。(Apache の場合)

service httpd restart

ライブラリのインストールまではできましたが、この時点で実行してみると

PHP Warning: geoip_record_by_name(): Required database not available at /usr/share/GeoIP/GeoIPCity.dat

データが無いよ、と怒られてしまいますので、上記の場所にデータを置くようにします。

cd /usr/share/GeoIP/

まず GeoIP ディレクトリに移動

wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz

最新のデータをダウンロード

gunzip GeoLiteCity.dat.gz

ダウンロードしたデータを解凍

mv GeoLiteCity.dat GeoIPCity.dat

データのファイル名を変更

以上で GeoIP のPHP関数が呼べる環境が整いました。

関数は geoip_record_by_name(IP_ADDRESS) の形で呼び出します。

array(11) {
  [“continent_code”]=>  string(2) “AS”
  [“country_code”]=>  string(2) “JP”
  [“country_code3”]=>  string(3) “JPN”
  [“country_name”]=>  string(5) “Japan”
  [“region”]=>  string(2) “32”
  [“city”]=>  string(5) “Osaka”
  [“postal_code”]=>  string(8) “543-0062”
  [“latitude”]=>  float(34.686401367188)
  [“longitude”]=>  float(135.52000427246)
  [“dma_code”]=>  int(0)
  [“area_code”]=>  int(0)
}

上記は var_dump の出力結果です。

無事に地域が取得できました。

正確性を求めると変なことになると思いますので、あくまで大まかな地域(けっこうずれていることもある)ぐらいな前提で使ったほうが良いと思います。

テスト用に あなたの情報を表示するページ を作ってみましたので試してみてください。
IPアドレスを入力して地域を表示するページも作りました。