お知らせ

現在サイトのリニューアル作業中のため、表示が崩れているページが存在することがあります。

PHPでIPv6によるアクセスから国情報を取得する

投稿日:ネットワーク::IPv6言語::PHP

日本国内からのアクセスを識別するときに、IPv4の頃はリモートホスト名が/\.jp$/であるかや、nifty.comみたいな例外を個別で見てやる程度で何とかなっていたが、IPv6は逆引きができないので、それをどうにか解決する方法。

確認環境

Env Ver
PHP 8.3.8
geoip2/geoip2 3.2.0

やり方

  1. ComposerでGeoIp2を入れる
    php composer.phar require geoip2/geoip2
    
  2. dbipからIP to City Lite databaseのMMDBを落としてくる。
    https://download.db-ip.com/free/dbip-city-lite-2025-11.mmdb.gzのURL形式なのでYYYYとMMのとこをいじっても落とせる。
  3. こんな感じにコードを書く

    <?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'
    

参考

あとがき

国情報を利用してアクセスを弾く必要があったので雑に調べて導入したが、dbipの無料DBは正確性が低いので、個人の小規模利用向けだと思う。

エンタープライズ用途などで制度が必要な場合は有料DBの契約を検討したほうがいいだろう。

しかしGeoIp2はPHPのマニュアルにあるからPHPに組み込みで存在してるのかと思ったら、まさかのComposerで驚いた。PHPも変わったなぁ…とかしみじみ。

でも昔からPearはあったような気もするし、今更か…?