1# GeoIP2 PHP API #
2
3## Description ##
4
5This package provides an API for the GeoIP2
6[web services](http://dev.maxmind.com/geoip/geoip2/web-services) and
7[databases](http://dev.maxmind.com/geoip/geoip2/downloadable). The API also
8works with the free
9[GeoLite2 databases](http://dev.maxmind.com/geoip/geoip2/geolite2/).
10
11## Install via Composer ##
12
13We recommend installing this package with [Composer](http://getcomposer.org/).
14
15### Download Composer ###
16
17To download Composer, run in the root directory of your project:
18
19```bash
20curl -sS https://getcomposer.org/installer | php
21```
22
23You should now have the file `composer.phar` in your project directory.
24
25### Install Dependencies ###
26
27Run in your project root:
28
29```
30php composer.phar require geoip2/geoip2:~2.0
31```
32
33You should now have the files `composer.json` and `composer.lock` as well as
34the directory `vendor` in your project directory. If you use a version control
35system, `composer.json` should be added to it.
36
37### Require Autoloader ###
38
39After installing the dependencies, you need to require the Composer autoloader
40from your code:
41
42```php
43require 'vendor/autoload.php';
44```
45
46## Install via Phar ##
47
48Although we strongly recommend using Composer, we also provide a
49[phar archive](http://php.net/manual/en/book.phar.php) containing most of the
50dependencies for GeoIP2. Our latest phar archive is available on
51[our releases page](https://github.com/maxmind/GeoIP2-php/releases).
52
53### Install Dependencies ###
54
55In order to use the phar archive, you must have the PHP
56[Phar extension](http://php.net/manual/en/book.phar.php) installed and
57enabled.
58
59If you will be making web service requests, you must have the PHP
60[cURL extension](http://php.net/manual/en/book.curl.php)
61installed to use this archive. For Debian based distributions, this can
62typically be found in the the `php-curl` package. For other operating
63systems, please consult the relevant documentation. After installing the
64extension you may need to restart your web server.
65
66If you are missing this extension, you will see errors like the following:
67
68```
69PHP Fatal error:  Uncaught Error: Call to undefined function MaxMind\WebService\curl_version()
70```
71
72### Require Package ###
73
74To use the archive, just require it from your script:
75
76```php
77require 'geoip2.phar';
78```
79
80## Optional C Extension ##
81
82The [MaxMind DB API](https://github.com/maxmind/MaxMind-DB-Reader-php)
83includes an optional C extension that you may install to dramatically increase
84the performance of lookups in GeoIP2 or GeoLite2 databases. To install, please
85follow the instructions included with that API.
86
87The extension has no effect on web-service lookups.
88
89## IP Geolocation Usage ##
90
91IP geolocation is inherently imprecise. Locations are often near the center of
92the population. Any location provided by a GeoIP2 database or web service
93should not be used to identify a particular address or household.
94
95## Database Reader ##
96
97### Usage ###
98
99To use this API, you must create a new `\GeoIp2\Database\Reader` object with
100the path to the database file as the first argument to the constructor. You
101may then call the method corresponding to the database you are using.
102
103If the lookup succeeds, the method call will return a model class for the
104record in the database. This model in turn contains multiple container
105classes for the different parts of the data such as the city in which the
106IP address is located.
107
108If the record is not found, a `\GeoIp2\Exception\AddressNotFoundException`
109is thrown. If the database is invalid or corrupt, a
110`\MaxMind\Db\InvalidDatabaseException` will be thrown.
111
112See the API documentation for more details.
113
114### City Example ###
115
116```php
117<?php
118require_once 'vendor/autoload.php';
119use GeoIp2\Database\Reader;
120
121// This creates the Reader object, which should be reused across
122// lookups.
123$reader = new Reader('/usr/local/share/GeoIP/GeoIP2-City.mmdb');
124
125// Replace "city" with the appropriate method for your database, e.g.,
126// "country".
127$record = $reader->city('128.101.101.101');
128
129print($record->country->isoCode . "\n"); // 'US'
130print($record->country->name . "\n"); // 'United States'
131print($record->country->names['zh-CN'] . "\n"); // '美国'
132
133print($record->mostSpecificSubdivision->name . "\n"); // 'Minnesota'
134print($record->mostSpecificSubdivision->isoCode . "\n"); // 'MN'
135
136print($record->city->name . "\n"); // 'Minneapolis'
137
138print($record->postal->code . "\n"); // '55455'
139
140print($record->location->latitude . "\n"); // 44.9733
141print($record->location->longitude . "\n"); // -93.2323
142
143```
144
145### Anonymous IP Example ###
146
147```php
148<?php
149require_once 'vendor/autoload.php';
150use GeoIp2\Database\Reader;
151
152// This creates the Reader object, which should be reused across
153// lookups.
154$reader = new Reader('/usr/local/share/GeoIP/GeoIP2-Anonymous-IP.mmdb');
155
156$record = $reader->anonymousIp('128.101.101.101');
157
158if ($record->isAnonymous) { print "anon\n"; }
159print($record->ipAddress . "\n"); // '128.101.101.101'
160
161```
162
163### Connection-Type Example ###
164
165```php
166<?php
167require_once 'vendor/autoload.php';
168use GeoIp2\Database\Reader;
169
170// This creates the Reader object, which should be reused across
171// lookups.
172$reader = new Reader('/usr/local/share/GeoIP/GeoIP2-Connection-Type.mmdb');
173
174$record = $reader->connectionType('128.101.101.101');
175
176print($record->connectionType . "\n"); // 'Corporate'
177print($record->ipAddress . "\n"); // '128.101.101.101'
178
179```
180
181### Domain Example ###
182
183```php
184<?php
185require_once 'vendor/autoload.php';
186use GeoIp2\Database\Reader;
187
188// This creates the Reader object, which should be reused across
189// lookups.
190$reader = new Reader('/usr/local/share/GeoIP/GeoIP2-Domain.mmdb');
191
192$record = $reader->domain('128.101.101.101');
193
194print($record->domain . "\n"); // 'umn.edu'
195print($record->ipAddress . "\n"); // '128.101.101.101'
196
197```
198
199### Enterprise Example ###
200
201```php
202<?php
203require_once 'vendor/autoload.php';
204use GeoIp2\Database\Reader;
205
206// This creates the Reader object, which should be reused across
207// lookups.
208$reader = new Reader('/usr/local/share/GeoIP/GeoIP2-Enterprise.mmdb');
209
210// Use the ->enterprise method to do a lookup in the Enterprise database
211$record = $reader->enterprise('128.101.101.101');
212
213print($record->country->confidence . "\n"); // 99
214print($record->country->isoCode . "\n"); // 'US'
215print($record->country->name . "\n"); // 'United States'
216print($record->country->names['zh-CN'] . "\n"); // '美国'
217
218print($record->mostSpecificSubdivision->confidence . "\n"); // 77
219print($record->mostSpecificSubdivision->name . "\n"); // 'Minnesota'
220print($record->mostSpecificSubdivision->isoCode . "\n"); // 'MN'
221
222print($record->city->confidence . "\n"); // 60
223print($record->city->name . "\n"); // 'Minneapolis'
224
225print($record->postal->code . "\n"); // '55455'
226
227print($record->location->accuracyRadius . "\n"); // 50
228print($record->location->latitude . "\n"); // 44.9733
229print($record->location->longitude . "\n"); // -93.2323
230
231```
232
233### ISP Example ###
234
235```php
236<?php
237require_once 'vendor/autoload.php';
238use GeoIp2\Database\Reader;
239
240// This creates the Reader object, which should be reused across
241// lookups.
242$reader = new Reader('/usr/local/share/GeoIP/GeoIP2-ISP.mmdb');
243
244$record = $reader->isp('128.101.101.101');
245
246print($record->autonomousSystemNumber . "\n"); // 217
247print($record->autonomousSystemOrganization . "\n"); // 'University of Minnesota'
248print($record->isp . "\n"); // 'University of Minnesota'
249print($record->organization . "\n"); // 'University of Minnesota'
250
251print($record->ipAddress . "\n"); // '128.101.101.101'
252
253```
254
255## Web Service Client ##
256
257### Usage ###
258
259To use this API, you must create a new `\GeoIp2\WebService\Client`
260object with your `$accountId` and `$licenseKey`, then you call the method
261corresponding to a specific end point, passing it the IP address you want to
262look up.
263
264If the request succeeds, the method call will return a model class for the end
265point you called. This model in turn contains multiple record classes, each of
266which represents part of the data returned by the web service.
267
268If there is an error, a structured exception is thrown.
269
270See the API documentation for more details.
271
272### Example ###
273
274```php
275<?php
276require_once 'vendor/autoload.php';
277use GeoIp2\WebService\Client;
278
279// This creates a Client object that can be reused across requests.
280// Replace "42" with your account ID and "license_key" with your license
281// key.
282$client = new Client(42, 'abcdef123456');
283
284// Replace "city" with the method corresponding to the web service that
285// you are using, e.g., "country", "insights".
286$record = $client->city('128.101.101.101');
287
288print($record->country->isoCode . "\n"); // 'US'
289print($record->country->name . "\n"); // 'United States'
290print($record->country->names['zh-CN'] . "\n"); // '美国'
291
292print($record->mostSpecificSubdivision->name . "\n"); // 'Minnesota'
293print($record->mostSpecificSubdivision->isoCode . "\n"); // 'MN'
294
295print($record->city->name . "\n"); // 'Minneapolis'
296
297print($record->postal->code . "\n"); // '55455'
298
299print($record->location->latitude . "\n"); // 44.9733
300print($record->location->longitude . "\n"); // -93.2323
301
302```
303
304## Values to use for Database or Array Keys ##
305
306**We strongly discourage you from using a value from any `names` property as
307a key in a database or array.**
308
309These names may change between releases. Instead we recommend using one of the
310following:
311
312* `GeoIp2\Record\City` - `$city->geonameId`
313* `GeoIp2\Record\Continent` - `$continent->code` or `$continent->geonameId`
314* `GeoIp2\Record\Country` and `GeoIp2\Record\RepresentedCountry` -
315  `$country->isoCode` or `$country->geonameId`
316* `GeoIp2\Record\Subdivision` - `$subdivision->isoCode` or `$subdivision->geonameId`
317
318### What data is returned? ###
319
320While many of the end points return the same basic records, the attributes
321which can be populated vary between end points. In addition, while an end
322point may offer a particular piece of data, MaxMind does not always have every
323piece of data for any given IP address.
324
325Because of these factors, it is possible for any end point to return a record
326where some or all of the attributes are unpopulated.
327
328See the
329[GeoIP2 Precision web service docs](http://dev.maxmind.com/geoip/geoip2/web-services)
330for details on what data each end point may return.
331
332The only piece of data which is always returned is the `ipAddress`
333attribute in the `GeoIp2\Record\Traits` record.
334
335## Integration with GeoNames ##
336
337[GeoNames](http://www.geonames.org/) offers web services and downloadable
338databases with data on geographical features around the world, including
339populated places. They offer both free and paid premium data. Each
340feature is unique identified by a `geonameId`, which is an integer.
341
342Many of the records returned by the GeoIP2 web services and databases
343include a `geonameId` property. This is the ID of a geographical feature
344(city, region, country, etc.) in the GeoNames database.
345
346Some of the data that MaxMind provides is also sourced from GeoNames. We
347source things like place names, ISO codes, and other similar data from
348the GeoNames premium data set.
349
350## Reporting data problems ##
351
352If the problem you find is that an IP address is incorrectly mapped,
353please
354[submit your correction to MaxMind](http://www.maxmind.com/en/correction).
355
356If you find some other sort of mistake, like an incorrect spelling,
357please check the [GeoNames site](http://www.geonames.org/) first. Once
358you've searched for a place and found it on the GeoNames map view, there
359are a number of links you can use to correct data ("move", "edit",
360"alternate names", etc.). Once the correction is part of the GeoNames
361data set, it will be automatically incorporated into future MaxMind
362releases.
363
364If you are a paying MaxMind customer and you're not sure where to submit
365a correction, please
366[contact MaxMind support](http://www.maxmind.com/en/support) for help.
367
368## Other Support ##
369
370Please report all issues with this code using the
371[GitHub issue tracker](https://github.com/maxmind/GeoIP2-php/issues).
372
373If you are having an issue with a MaxMind service that is not specific
374to the client API, please see
375[our support page](http://www.maxmind.com/en/support).
376
377## Requirements  ##
378
379This library requires PHP 5.4 or greater. This library works and is tested
380with HHVM.
381
382This library also relies on the [MaxMind DB Reader](https://github.com/maxmind/MaxMind-DB-Reader-php).
383
384## Contributing ##
385
386Patches and pull requests are encouraged. All code should follow the PSR-2
387style guidelines. Please include unit tests whenever possible. You may obtain
388the test data for the maxmind-db folder by running `git submodule update
389--init --recursive` or adding `--recursive` to your initial clone, or from
390https://github.com/maxmind/MaxMind-DB
391
392## Versioning ##
393
394The GeoIP2 PHP API uses [Semantic Versioning](http://semver.org/).
395
396## Copyright and License ##
397
398This software is Copyright (c) 2013-2018 by MaxMind, Inc.
399
400This is free software, licensed under the Apache License, Version 2.0.
401
402