PHPでIPv6によるアクセスから国情報を取得する
投稿日:
日本国内からのアクセスを識別するときに、IPv4の頃はリモートホスト名が/\.jp$/であるかや、nifty.comみたいな例外を個別で見てやる程度で何とかなっていたが、IPv6は逆引きができないので、それをどうにか解決する方法。
確認環境
| Env | Ver |
|---|---|
| PHP | 8.3.8 |
| geoip2/geoip2 | 3.2.0 |
やり方
- ComposerでGeoIp2を入れる
php composer.phar require geoip2/geoip2 - dbipからIP to City Lite databaseのMMDBを落としてくる。
https://download.db-ip.com/free/dbip-city-lite-2025-11.mmdb.gzのURL形式なのでYYYYとMMのとこをいじっても落とせる。 こんな感じにコードを書く
<?php require 'vendor/autoload.php'; use GeoIp2\Database\Reader; // 落としてきたMMDBを指定 $cityDbReader = new Reader('dbip-city-lite-2025-11.mmdb'); // IPを渡すと結果が取れる $record = $cityDbReader->city('2403:6200:8860:e103:a4b2:ff66:9e68:6436'); print($record->country->isoCode . "\n"); // 'US' print($record->country->name . "\n"); // 'United States' print($record->country->names['zh-CN'] . "\n"); // '美国' print($record->mostSpecificSubdivision->name . "\n"); // 'Minnesota' print($record->mostSpecificSubdivision->isoCode . "\n"); // 'MN' print($record->city->name . "\n"); // 'Minneapolis' print($record->postal->code . "\n"); // '55455' print($record->location->latitude . "\n"); // 44.9733 print($record->location->longitude . "\n"); // -93.2323 print($record->traits->network . "\n"); // '128.101.101.101/32'
参考
- GeoIP extension Introduction - www.php.net
- GeoIP2 PHP API - maxmind.github.io
あとがき
国情報を利用してアクセスを弾く必要があったので雑に調べて導入したが、dbipの無料DBは正確性が低いので、個人の小規模利用向けだと思う。
エンタープライズ用途などで制度が必要な場合は有料DBの契約を検討したほうがいいだろう。
しかしGeoIp2はPHPのマニュアルにあるからPHPに組み込みで存在してるのかと思ったら、まさかのComposerで驚いた。PHPも変わったなぁ…とかしみじみ。
でも昔からPearはあったような気もするし、今更か…?