Geoip2
인증된 제출자geoip2/geoip2
MaxMind GeoIP PHP API
GeoIP2 PHP API
개요
이 패키지는 MaxMind의 GeoIP 및 GeoLite 웹 서비스와 데이터베이스를 PHP에서 쉽게 사용할 수 있도록 API를 제공합니다.
Composer를 이용한 설치
이 패키지는 Composer를 통해 설치하는 것을 권장합니다.
Composer 다운로드
프로젝트 루트 디렉터리에서 아래 명령어를 실행하면 Composer를 내려받을 수 있습니다.
curl -sS https://getcomposer.org/installer | php실행 후 프로젝트 디렉터리에 composer.phar 파일이 생성됩니다.
의존성 설치
프로젝트 루트에서 다음 명령어를 실행합니다.
php composer.phar require geoip2/geoip2:^3.4.0설치가 완료되면 composer.json, composer.lock 파일과 vendor 디렉터리가 생성됩니다. 버전 관리 시스템을 사용하는 경우 composer.json은 저장소에 포함하고, vendor 디렉터리는 .gitignore에 추가하는 것이 일반적입니다.
오토로더 등록
의존성 설치 후, 코드에서 Composer 오토로더를 불러옵니다.
require 'vendor/autoload.php';Phar 아카이브를 이용한 설치
Composer 사용을 강력히 권장하지만, 대부분의 의존성이 포함된 phar 아카이브도 제공합니다. 최신 phar 파일은 GitHub 릴리스 페이지에서 내려받을 수 있습니다.
사전 요구 사항
phar 아카이브를 사용하려면 PHP Phar 확장이 설치 및 활성화되어 있어야 합니다.
웹 서비스 요청을 사용할 계획이라면 PHP cURL 확장도 필요합니다. Debian 계열 배포판(Ubuntu 등)에서는 보통 php-curl 패키지로 설치할 수 있습니다. 다른 운영 체제는 해당 문서를 참고하세요. 확장을 설치한 후에는 웹 서버를 재시작해야 할 수 있습니다.
cURL 확장이 없으면 다음과 같은 오류가 발생합니다.
PHP Fatal error: Uncaught Error: Call to undefined function MaxMind\WebService\curl_version()
phar 파일 불러오기
다운로드한 phar 파일을 스크립트에서 아래와 같이 불러옵니다.
require 'geoip2.phar';선택적 C 확장
MaxMind DB API는 선택적으로 C 확장을 제공합니다. 이 확장을 설치하면 GeoIP 또는 GeoLite 데이터베이스 조회 성능이 크게 향상됩니다. 설치 방법은 해당 API에 포함된 안내를 참고하세요.
NOTE
C 확장은 데이터베이스 조회 성능에만 영향을 줍니다. 웹 서비스 조회에는 효과가 없습니다.
IP 지리 정보 사용 시 주의 사항
IP 기반 지리 정보는 본질적으로 정확도에 한계가 있습니다. 반환되는 위치 정보는 대개 해당 인구 집중 지역의 중심에 가까운 값입니다. GeoIP 데이터베이스나 웹 서비스가 제공하는 위치 정보를 특정 주소나 가구를 식별하는 용도로 사용해서는 안 됩니다.
데이터베이스 리더
기본 사용 방법
\GeoIp2\Database\Reader 객체를 생성할 때 첫 번째 인수로 데이터베이스 파일 경로를 전달합니다. 이후 사용 중인 데이터베이스에 맞는 메서드를 호출하면 됩니다.
조회에 성공하면 해당 레코드에 대한 모델 클래스가 반환되며, 이 모델은 도시, 국가 등 각 데이터 영역에 대한 컨테이너 클래스를 포함합니다.
- 레코드를 찾지 못한 경우:
\GeoIp2\Exception\AddressNotFoundException발생 - 데이터베이스가 유효하지 않거나 손상된 경우:
\MaxMind\Db\InvalidDatabaseException발생
더 자세한 내용은 API 문서를 참고하세요.
NOTE
Reader 객체는 조회마다 새로 생성하지 말고, 한 번 만든 뒤 여러 조회에 재사용하는 것이 성능상 유리합니다.
City 데이터베이스 예제
<?php
require_once 'vendor/autoload.php';
use GeoIp2\Database\Reader;
// Reader 객체는 여러 번의 조회에 재사용하는 것을 권장합니다.
$cityDbReader = new Reader('/usr/local/share/GeoIP/GeoIP2-City.mmdb');
// 사용 중인 데이터베이스에 맞게 메서드를 변경하세요 (예: "country").
$record = $cityDbReader->city('128.101.101.101');
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'익명 IP 데이터베이스 예제
<?php
require_once 'vendor/autoload.php';
use GeoIp2\Database\Reader;
// Reader 객체는 여러 번의 조회에 재사용하는 것을 권장합니다.
$anonymousDbReader = new Reader('/usr/local/share/GeoIP/GeoIP2-Anonymous-IP.mmdb');
$record = $anonymousDbReader->anonymousIp('128.101.101.101');
if ($record->isAnonymous) { print "익명 IP\n"; }
print($record->ipAddress . "\n"); // '128.101.101.101'
print($record->network . "\n"); // '128.101.101.101/32'Anonymous Plus 데이터베이스 예제
<?php
require_once 'vendor/autoload.php';
use GeoIp2\Database\Reader;
// Reader 객체는 여러 번의 조회에 재사용하는 것을 권장합니다.
$anonymousDbReader = new Reader('/usr/local/share/GeoIP/GeoIP-Anonymous-Plus.mmdb');
$record = $anonymousDbReader->anonymousPlus('203.0.113.0');
print($record->anonymizerConfidence . "\n"); // 30
print($record->networkLastSeen . "\n"); // '2025-04-14'
print($record->providerName . "\n"); // 'FooBar VPN'
print($record->ipAddress . "\n"); // '203.0.113.0'
print($record->network . "\n"); // '203.0.113.0/32'연결 유형 데이터베이스 예제
<?php
require_once 'vendor/autoload.php';
use GeoIp2\Database\Reader;
// Reader 객체는 여러 번의 조회에 재사용하는 것을 권장합니다.
$connectionTypeDbReader = new Reader('/usr/local/share/GeoIP/GeoIP2-Connection-Type.mmdb');
$record = $connectionTypeDbReader->connectionType('128.101.101.101');
print($record->connectionType . "\n"); // 'Corporate'
print($record->ipAddress . "\n"); // '128.101.101.101'
print($record->network . "\n"); // '128.101.101.101/32'도메인 데이터베이스 예제
<?php
require_once 'vendor/autoload.php';
use GeoIp2\Database\Reader;
// Reader 객체는 여러 번의 조회에 재사용하는 것을 권장합니다.
$domainDbReader = new Reader('/usr/local/share/GeoIP/GeoIP2-Domain.mmdb');
$record = $domainDbReader->domain('128.101.101.101');
print($record->domain . "\n"); // 'umn.edu'
print($record->ipAddress . "\n"); // '128.101.101.101'
print($record->network . "\n"); // '128.101.101.101/32'Enterprise 데이터베이스 예제
<?php
require_once 'vendor/autoload.php';
use GeoIp2\Database\Reader;
// Reader 객체는 여러 번의 조회에 재사용하는 것을 권장합니다.
$enterpriseDbReader = new Reader('/usr/local/share/GeoIP/GeoIP2-Enterprise.mmdb');
// Enterprise 데이터베이스 조회에는 ->enterprise 메서드를 사용합니다.
$record = $enterpriseDbReader->enterprise('128.101.101.101');
print($record->country->confidence . "\n"); // 99
print($record->country->isoCode . "\n"); // 'US'
print($record->country->name . "\n"); // 'United States'
print($record->country->names['zh-CN'] . "\n"); // '美国'
print($record->mostSpecificSubdivision->confidence . "\n"); // 77
print($record->mostSpecificSubdivision->name . "\n"); // 'Minnesota'
print($record->mostSpecificSubdivision->isoCode . "\n"); // 'MN'
print($record->city->confidence . "\n"); // 60
print($record->city->name . "\n"); // 'Minneapolis'
print($record->postal->code . "\n"); // '55455'
print($record->location->accuracyRadius . "\n"); // 50
print($record->location->latitude . "\n"); // 44.9733
print($record->location->longitude . "\n"); // -93.2323
print($record->traits->network . "\n"); // '128.101.101.101/32'ISP 데이터베이스 예제
<?php
require_once 'vendor/autoload.php';
use GeoIp2\Database\Reader;
// Reader 객체는 여러 번의 조회에 재사용하는 것을 권장합니다.
$ispDbReader = new Reader('/usr/local/share/GeoIP/GeoIP2-ISP.mmdb');
$record = $ispDbReader->isp('128.101.101.101');
print($record->autonomousSystemNumber . "\n"); // 217
print($record->autonomousSystemOrganization . "\n"); // 'University of Minnesota'
print($record->isp . "\n"); // 'University of Minnesota'
print($record->organization . "\n"); // 'University of Minnesota'
print($record->ipAddress . "\n"); // '128.101.101.101'
print($record->network . "\n"); // '128.101.101.101/32'데이터베이스 업데이트
GeoIP Update 프로그램을 사용하면 데이터베이스를 최신 상태로 유지할 수 있습니다. 자세한 내용은 MaxMind 개발자 포털의 데이터베이스 업데이트 가이드를 참고하세요.
웹 서비스 클라이언트
기본 사용 방법
\GeoIp2\WebService\Client 객체를 생성할 때 $accountId와 $licenseKey를 전달합니다.
$client = new Client(42, 'abcdef123456');생성자에 추가 인수를 전달할 수도 있습니다. 세 번째 인수는 모델 클래스의 ->name 속성 사용 시 적용할 언어 우선순위이며, 네 번째 인수는 host, timeout 등의 추가 옵션입니다.
GeoIP 웹 서비스 대신 GeoLite 웹 서비스를 사용하려면 다음과 같이 설정합니다.
$client = new Client(42, 'abcdef123456', ['en'], ['host' => 'geolite.info']);운영 환경 대신 Sandbox GeoIP 웹 서비스를 사용하려면 다음과 같이 설정합니다.
$client = new Client(42, 'abcdef123456', ['en'], ['host' => 'sandbox.maxmind.com']);클라이언트를 생성한 후에는 조회하려는 엔드포인트에 해당하는 메서드를 IP 주소와 함께 호출합니다.
$record = $client->city('128.101.101.101');요청에 성공하면 해당 엔드포인트에 대한 모델 클래스가 반환됩니다. 오류가 발생하면 구조화된 예외가 throw됩니다.
더 자세한 내용은 API 문서를 참고하세요.
웹 서비스 전체 예제
<?php
require_once 'vendor/autoload.php';
use GeoIp2\WebService\Client;
// 여러 요청에 재사용할 수 있는 Client 객체를 생성합니다.
// "42"를 실제 계정 ID로, "abcdef123456"을 실제 라이선스 키로 교체하세요.
// GeoLite 웹 서비스를 사용하려면 네 번째 인수에 ['host' => 'geolite.info']를 지정하세요.
// Sandbox 환경을 사용하려면 ['host' => 'sandbox.maxmind.com']을 지정하세요.
$client = new Client(42, 'abcdef123456');
// 사용하는 웹 서비스에 맞게 메서드를 변경하세요 (예: "country", "insights").
$record = $client->city('128.101.101.101');
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'데이터베이스 또는 배열 키로 사용할 값
NOTE
names 속성의 값을 데이터베이스나 배열의 키로 사용하는 것은 강력히 권장하지 않습니다. 이 이름들은 라이브러리 릴리스 사이에 변경될 수 있습니다.
키로 사용할 안정적인 식별자로는 다음을 권장합니다.
GeoIp2\Record\City—$city->geonameIdGeoIp2\Record\Continent—$continent->code또는$continent->geonameIdGeoIp2\Record\Country및GeoIp2\Record\RepresentedCountry—$country->isoCode또는$country->geonameIdGeoIp2\Record\Subdivision—$subdivision->isoCode또는$subdivision->geonameId
반환되는 데이터에 대하여
여러 엔드포인트가 동일한 기본 레코드 구조를 반환하지만, 실제로 값이 채워지는 속성은 엔드포인트마다 다릅니다. 또한 MaxMind가 모든 IP 주소에 대해 모든 데이터를 보유하고 있지는 않으므로, 일부 또는 전체 속성이 비어 있는 레코드가 반환될 수 있습니다.
각 엔드포인트가 반환할 수 있는 데이터의 상세 내역은 GeoIP 웹 서비스 문서를 참고하세요.
항상 반환이 보장되는 데이터는 GeoIp2\Record\Traits 레코드의 ipAddress 속성뿐입니다.
GeoNames 연동
GeoNames는 전 세계 지리적 특성(도시, 지역, 국가 등) 데이터를 제공하는 웹 서비스 및 다운로드 가능한 데이터베이스입니다. 각 지리적 특성은 정수형 geonameId로 고유하게 식별됩니다.
GeoIP 웹 서비스 및 데이터베이스가 반환하는 많은 레코드에는 geonameId 속성이 포함되어 있으며, 이를 통해 GeoNames 데이터와 연동할 수 있습니다.
MaxMind는 지명, ISO 코드 등 일부 데이터를 GeoNames 프리미엄 데이터셋에서 가져옵니다.
데이터 오류 신고
IP 주소 위치 매핑이 잘못된 경우: MaxMind 데이터 수정 요청 페이지에 수정을 제출하세요.
지명 오타 등 다른 종류의 오류: 먼저 GeoNames 사이트에서 해당 장소를 검색한 후 지도 뷰에서 "move", "edit", "alternate names" 등의 링크를 통해 수정할 수 있습니다. GeoNames 데이터셋에 수정이 반영되면 이후 MaxMind 릴리스에 자동으로 포함됩니다.
MaxMind 유료 고객으로서 어디에 수정을 제출해야 할지 모르겠다면 MaxMind 고객 지원에 문의하세요.
기타 지원
코드 관련 문제는 GitHub 이슈 트래커를 통해 보고해 주세요.
클라이언트 API와 무관한 MaxMind 서비스 관련 문제는 지원 페이지를 참고하세요.
시스템 요구 사항
- PHP 8.1 이상
- MaxMind DB Reader
기여하기
패치와 풀 리퀘스트를 환영합니다. 모든 코드는 PSR-12 스타일 가이드라인을 따라야 하며, 가능한 경우 유닛 테스트를 함께 포함해 주세요. 테스트 데이터는 아래 명령어로 가져올 수 있습니다.
git submodule update --init --recursive또는 초기 클론 시 --recursive 옵션을 추가하거나, MaxMind-DB GitHub 저장소에서 직접 내려받을 수 있습니다.
버전 관리
GeoIP PHP API는 시맨틱 버저닝(Semantic Versioning)을 따릅니다.
저작권 및 라이선스
이 소프트웨어의 저작권은 2013-2026 MaxMind, Inc.에 있습니다.
Apache License, Version 2.0에 따라 자유롭게 사용할 수 있는 오픈 소스 소프트웨어입니다.