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