PHPでIPアドレスやホスト名から住所を求める

(1/1)
IP2Location.io は、IPアドレスから住所を求めることができるWebサービスだ。サイトへの訪問者の地理的位置を特定するために利用されている。
これと、Googleや地理院地図、オープンストリートマップの地図サービスをクラウド連携することで、アクセスしているIPアドレスやホスト名から住所を求めるPHPプログラムを作ってみることにする。

目次

サンプル・プログラムの実行例

PHPでIPアドレスやホスト名から住所を求める
Googleマップ表示

サンプル・プログラムのダウンロード

圧縮ファイルの内容
ip2address.phpサンプル・プログラム本体。
pahooGeoCode.php住所・緯度・経度に関わるクラス pahooGeoCode。
使い方は「PHPで住所・ランドマークから最寄り駅を求める」「PHPで住所・ランドマークから緯度・経度を求める」などを参照。include_path が通ったディレクトリに配置すること。
pahooInputData.phpデータ入力に関わる関数群。
使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。
ip2address.php 更新履歴
バージョン 更新日 内容
1.0.0 2022/12/31 初版
pahooGeoCode.php 更新履歴
バージョン 更新日 内容
6.1.0 2022/12/30 ip2address()追加
6.0.4 2022/12/13 PHP8.2対応
6.03 2022/05/29 マップにプロットできる場所を999箇所に拡大
6.02 2022/03/19 drawLeaflet()で移動時の緯度・経度を拾わないbug-fix
6.01 2021/12/06 bug-fix
pahooInputData.php 更新履歴
バージョン 更新日 内容
1.1.2 2023/02/05 validString() 修正
1.11 2022/07/03 isCommandLine() 修正
1.1 2022/06/04 getValidString() 修正
1.0 2022/05/18 初版

サンプル・プログラムの流れ

PHPでIPアドレスやホスト名から住所を求める

準備:pahooGeoCode クラス

  37: class pahooGeoCode {
  38:     var $items;     //検索結果格納用
  39:     var $error;     //エラー・フラグ
  40:     var $errmsg;    //エラー・メッセージ
  41:     var $hits;      //検索ヒット件数
  42:     var $webapi;    //直前に呼び出したWebAPI URL
  43: 
  44:     //Google Cloud Platform APIキー
  45:     //https://cloud.google.com/maps-platform/
  46:     //※Google Maps APIを利用しないのなら登録不要
  47:     var $GOOGLE_API_KEY_1 = '**************************';   //HTTPリファラ用
  48:     var $GOOGLE_API_KEY_2 = '**************************';   //IP制限用
  49: 
  50:     //Yahoo! JAPAN Webサービス アプリケーションID
  51:     //https://e.developer.yahoo.co.jp/register
  52:     //※Yahoo! JAPAN Webサービスを利用しないのなら登録不要
  53:     var $YAHOO_APPLICATION_ID = '*****************************';
  54: 
  55:     //ジオどすII APIキー【廃止】
  56:     //http://geodosu.com/user/register
  57:     var $APIKEY_GEODOS = '*****************';
  58: 
  59:     //IP2Location.io APIキー
  60:     //https://www.ip2location.io/
  61:     //※IP2Location.ioを利用しないのなら登録不要
  62:     var $IP2LOCATION_API_KEY = '*****************';

地図描画や住所検索を行うために、クラスファイル "pahooGeoCode.php" を使用する。組み込み関数  require_once  を使って読めるディレクトリに配置する。ディレクトリは、設定ファイル php.ini に記述されているオプション設定 include_path に設定しておく。
クラスについては「PHPでクラスを使ってテキストの読みやすさを調べる」を参照されたい。

地図や住所検索として Google を利用するのであれば、Google Cloud Platform APIキー が必要で、その入手方法は「Google Cloud Platform - WebAPIの登録方法」を、Yahoo!JAPAN を利用するのであれば、Yahoo! JAPAN Webサービス アプリケーションIDが必要で、その入手方法は「Yahoo!JAPAN デベロッパーネットワーク - WebAPIの登録方法」を、それぞれ参照されたい。

IP2Location.ioAPIキーの入手方法は、「IP2Location.io - WebAPIの登録方法」を参照されたい。

準備:地図サービスの選択

  38: //地図描画サービスの選択
  39: //    0:Google
  40: //    2:地理院地図・OSM
  41: define('MAPSERVICE', 2);
  42: 
  43: //逆ジオコーディングサービスの選択
  44: //    0:Google
  45: //    1:Yahoo!JAPAN
  46: //   11:HeartRails Geo API
  47: //   21:簡易ジオコーディングサービス
  48: define('REVGEOSERVICE', 21);

表示する地図は、Googleマップ地理院地図・オープンストリートマップ(OSM)から選べる。あらかじめ、定数 MAPSERVIC に値を設定すること。
住所検索サービスは、GoogleYahoo!JAPANHeartRails Geo APIから選べる。あらかじめ、定数 GEOSERVICE に値を設定すること。
逆ジオコーディングサービスは、GoogleYahoo!JAPANHeartRails Geo API簡易ジオコーディングサービスから選べる。あらかじめ、定数 REVGEOSERVICE に値を設定すること。

解説:IP2Location.io による位置情報取得

IP2LOCATION.IO IP GEOLOCATION API」は、入力パラメータ(IN)は GET 渡しで、出力結果(OUT)は JSON などで戻すという形である。今回使う入力パラメータと出力結果のデータ構造を以下に示す。得られる緯度・経度は世界測地系(wgs84)であることに留意されたい。
WebAPI
URL
https://api.ip2location.io/
入力パラメータ
フィールド名 要否 内  容
key 必須 IP2LOCATION.IO IP GEOLOCATION APIを利用するためのアプリケーション・キー
ip 必須 検索するIPアドレス(IPv4またはIPv6)
format 省略可能 出力書式。jsonまたはxml
lang 省略可能 言語。ISO639-1による。日本なら ja
応答データ(json) ip IPアドレス(IPv4またはIPv6) country_code 国コード(ISO639-1) country_name 国名 region_name 地域名 city_name 市区町村名 latitude 緯度(10進小数) longitude 経度(10進小数) zip_code 郵便番号 time_zone タイムゾーン as AS番号 asn AS名 isp ISP名 is_proxy プロキシ経由かどうか(true/false)

解説:IP2LOCATION.IO IP GEOLOCATION APIの呼び出し

2524: /**
2525:  * IP2Location.ioを用いてIPアドレスから緯度・経度を求める
2526:  * @param   string $ip IPアドレス
2527:  * @return  array($latitude, $longitude) 緯度, 経度(世界測地系,10進数の度表記)
2528: */
2529: function ip2address($ip) {
2530:     $res = FALSE;
2531: 
2532:     //IP2Location.io呼び出し
2533:     $url = 'https://api.ip2location.io/?key=' . $this->IP2LOCATION_API_KEY . '&ip=' . $ip . '&format=json';
2534:     $this->webapi = $url;
2535:     $json = @file_get_contents($url, FALSE);
2536: 
2537:     //レスポンス・チェック
2538:     if ($json == FALSE) {
2539:         $this->error = TRUE;
2540:         $this->errmsg = 'ip2locationにアクセスできません';
2541:     } else {
2542:         //APIからの応答取得
2543:         if ($this->isphp7over()) {
2544:             $arr = @json_decode($json, FALSE, 512, JSON_BIGINT_AS_STRING);
2545:         } else {
2546:             $arr = @json_decode($json, FALSE, 512);
2547:         }
2548:         if (isset($arr->latitude&& isset($arr->longitude)) {
2549:             $res = array((double)$arr->latitude, (double)$arr->longitude);
2550:         } else {
2551:             $this->error = TRUE;
2552:             $this->errmsg = 'IPアドレスが見つかりません';
2553:         }
2554:     }
2555: 
2556:     return $res;
2557: }

ip2address は、IP2LOCATION.IO IP GEOLOCATION API を呼び出して、緯度、経度のみを返すメソッドである。

解説:メイン・プログラム

メイン・プログラムは、これまで説明してきたクラウド連携・プログラムとほぼ同じである。

 287: //IPアドレスはREMOTE_ADDRから取得
 288: $ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR': '';
 289: if (is_ipadr($ip) == FALSE)     $ip = '';
 290: if ($ip == '')  $ip = DEF_QUERY;

初期値として使うIPアドレスは、「PHPでユーザー・アクセス情報を表示する」で紹介したプログラムを利用し、端末がインターネットにアクセスしているIPアドレス($_SERVER['REMOTE_ADDR'])を参照している。

 314: //ホスト名→IPアドレス変換
 315: if (($host = is_host($query)) !FALSE) {
 316:     $ip = gethostbyname($host);
 317: else {
 318:     $ip = $query;
 319: }

検索キーとして、IPアドレスだけでなくホスト名(ドメイン名を含む)の入力も許可した。そこで、「IPアドレスとドメイン名を相互変換する」で紹介したプログラムを利用し、入力値がホスト名だったらIPアドレスに変換する処理を加えた。

 329:     //エラーがなければ緯度・経度に代入
 330:     if ($res !FALSE) {
 331:         $latitude  = $res[0];
 332:         $longitude = $res[1];
 333:         //緯度・経度から住所を取得
 334:         $arr = $pgc->getAddress3($latitude, $longitude, REVGEOSERVICE);
 335:         if ($arr !FALSE) {
 336:             //住所は都道府県+市町村
 337:             $address = $arr['prefecture'. $arr['city'];
 338:             //マップに表示する情報ウィンドウの内容
 339:             $description = "IPアドレス:{$ip}<br />住所:{$address}<br />緯度:{$latitude},経度:{$longitude}";
 340:             $items[1] = array(
 341:                 'latitude'    => $latitude,
 342:                 'longitude'   => $longitude,
 343:                 'title'       => '',
 344:                 'description' => $description
 345:             );
 346:         }
 347:     } else {
 348:         $errmsg = $pgc->geterror();
 349:     }

ip2address から受け取った緯度・経度を、「PHPで緯度・経度から住所を求める」で紹介したメソッド getAddress3 を使って住所に変換する。
ここでは IP2Location.io の無償ライセンスを利用していることから位置情報の精度が低いため、住所として市町村名まで取得するようにした。

参考サイト

(この項おわり)
header