Search by

samsmithcodes / laravel-geoip2

samsmithcodes

A Laravel package to enable IP lookups on the GeoIP2 Lite databases.

Package info

gitlab.samsmith.codes/samsmithcodes/laravel-geoip2

pkg:composer/samsmithcodes/laravel-geoip2

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

1.0.0 2026-10-01 16:06 UTC

This package is auto-updated.

Last update: 2026-10-02 21:21:55 UTC


README

Laravel GeoIP2

Packagist PHP from Packagist Laravel versions Total Downloads

A Laravel package to enable IP lookups on the GeoIP2 Lite databases.

Installation

You can install the package via Composer:

composer require samsmithcodes/laravel-geoip2

You may publish the configuration file:

php artisan vendor:publish --tag="geoip2-config"

Usage

Testing

First, download MaxMind's test databases, which aren't committed to the repository (see Test databases):

for db in GeoLite2-City-Test GeoLite2-ASN-Test; do
    curl -fsSL --create-dirs -o "tests/Fixtures/$db.mmdb" \
      "https://raw.githubusercontent.com/maxmind/MaxMind-DB/main/test-data/$db.mmdb"
done

You only need to do this once. Then run the full test suite with Docker, so you don't need PHP installed locally:

docker run --rm -it \
  -v ${PWD}:/app \
  registry.samsmith.codes/samsmithcodes/laravel-starter-tools:latest composer test

To run something else, swap composer test at the end of the command for:

  • One of the steps below, e.g. composer lint to fix the code style.
  • A single test file, e.g. vendor/bin/pest tests/Feature/GeoIP2Test.php.
  • Only the tests with a name matching a filter, e.g. vendor/bin/pest --filter="checksum".

What composer test runs

The steps are Composer scripts, defined under scripts in composer.json. They run in this order, and stop at the first failure:

StepToolWhat it checksConfig
composer analysePHPStan with LarastanThe code is type safe and has no bugs it can findphpstan.neon.dist
composer lint:checkLaravel PintThe code style is consistentpint.json
composer test:typesPest type coverageEvery parameter, property and return in src has a typecomposer.json
composer test:unitPest with Orchestra TestbenchThe tests in tests pass, run in parallelphpunit.xml.dist, tests/Pest.php, tests/TestCase.php

The tools

Pest runs the tests. It's built on PHPUnit, so it reads PHPUnit's config:

  • phpunit.xml.dist lists the test suites (Arch, Feature and Unit) and the src directory being tested. It runs the tests in a random order, so they can't rely on each other, and fails on warnings or unexpected output. To add a test, create a file ending in Test.php in tests/Feature or tests/Unit and it's picked up automatically.
  • tests/Pest.php runs before the tests, and makes every test use TestCase. Add any helpers shared between test files here.
  • tests/ArchTest.php uses Pest's architecture testing to enforce rules across the code, e.g. strict types, and no dd() or insecure functions like md5().

Orchestra Testbench boots a minimal Laravel app for the tests, so the package is tested just as an app would use it:

  • tests/TestCase.php loads the package's service provider in getPackageProviders(), and sets the config every test starts with in defineEnvironment(), which points the databases at the test fixtures. A test can change config for itself with config([...]).
  • testbench.yaml and the workbench directory configure the app used by composer serve, for trying the package in a browser. The tests don't use them.

Pest type coverage checks everything in src has a type declared. It's configured by the options on the test:types script in composer.json: --min=100 is the percentage required, and --memory-limit raises PHP's memory limit, which the Docker image's default is too low for.

PHPStan, with the Larastan extension so it understands Laravel's facades and helpers, reads the code without running it to find bugs, e.g. passing the wrong type or calling a method that doesn't exist. phpstan.neon.dist sets:

  • level, how strict it is, from 0 to 10, currently 7.
  • paths, the directories it checks.
  • ignoreErrors, for false positives, each with a comment saying why. Only add one when the error is wrong, not to hide a real problem.

Laravel Pint checks the code style. pint.json uses Laravel's preset, with a few extra rules, e.g. a blank line before every return. composer lint:check only reports problems, while composer lint fixes them.

The tests

  • tests/ArchTest.php: architecture rules, e.g. every file declares strict types, and there are no debugging calls like dd() or insecure functions.
  • tests/Feature/GeoIP2Test.php: looks up real addresses in the test databases (City, ASN and IPv6), and checks the errors for invalid addresses, missing databases, and databases that are the wrong type. It also checks a database is reopened when its file changes, as happens after an update.
  • tests/Feature/UpdateCommandTest.php: runs geoip2:update against a fake MaxMind built with Http::fake(), which serves real archives containing the test databases. It covers downloading, skipping up to date databases, --force, missing or rejected credentials, and a bad checksum leaving the current database untouched. No real requests are made.
  • tests/Feature/ServiceProviderTest.php: the container bindings, config, Facade and command are registered.
  • tests/Unit/RecordTest.php: MaxMind's City and ASN models are mapped onto a Record correctly, including when one is missing.

Test databases

The tests use two of MaxMind's official test databases, which contain fake data for a handful of addresses:

  • GeoLite2-City-Test.mmdb
  • GeoLite2-ASN-Test.mmdb

They come from the maxmind/MaxMind-DB repository, and are downloaded into tests/Fixtures, where the tests load them with Pest's fixture() helper. They're ignored by Git, in .gitignore, so they aren't redistributed with this package. If they're missing, every test fails with "The fixture file [...] does not exist", so download them with the command at the top of this section.

The download always uses MaxMind's latest test data, from the main branch, so the tests keep up with any changes MaxMind makes. The tests check exact values from these databases, e.g. that 2.125.160.216 is in Boxford, so if MaxMind changes their test data some tests may start failing. When that happens, download the databases again and update the expected values in tests/Feature/GeoIP2Test.php. The source JSON shows which addresses each database contains.

The real GeoLite2 databases are never used in the tests.

License

Laravel GeoIP2 is open-sourced software licensed under the MIT license.