flairuk / laravel-world
Countries, cities, airports, airlines and aircraft for Laravel, joined up: one facade over the FLAIRUK data packages.
Requires
- php: ^8.2
- flairuk/laravel-aircrafts: ^1.0
- flairuk/laravel-airlines: ^1.0
- flairuk/laravel-airports: ^1.0
- flairuk/laravel-cities: ^1.0
- flairuk/laravel-countries: ^1.0
- illuminate/console: ^12.0|^13.0
- illuminate/support: ^12.0|^13.0
Requires (Dev)
- laravel/pint: ^1.18
- orchestra/testbench: ^10.0|^11.0
- phpunit/phpunit: ^11.5|^12.0|^13.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-05 12:56:07 UTC
README
Laravel World — Countries, cities, airports, airlines and aircraft for Laravel 12 and 13, joined up behind one facade.
- Every dataset. Installs all five FLAIRUK data packages, each still usable on its own.
- Joined through the country. Find a country by any of its codes, then its cities, airports and airlines.
- One search. Search every dataset by code or name in one call.
- No database required. Everything is looked up in memory. A command publishes and seeds all five tables when you need them.
📦 Installation · 🧭 Datasets · 🚀 Usage · 💾 Database tables
📦 Installation
composer require flairuk/laravel-world
Requires PHP 8.2 or later with Laravel 12, or PHP 8.3 or later with Laravel 13.
Laravel discovers the service providers and the World facade automatically.
🧭 Datasets
Each dataset is its own package, and laravel-world requires all five:
| Package | Data | Facade |
|---|---|---|
| flairuk/laravel-countries | ISO 3166 countries | Countries |
| flairuk/laravel-cities | IATA city codes | Cities |
| flairuk/laravel-airports | IATA airport codes | Airports |
| flairuk/laravel-airlines | IATA airline designators | Airlines |
| flairuk/laravel-aircrafts | IATA aircraft type codes | Aircrafts |
Their facades, validation rules and models all work as their READMEs describe. World adds what none of them can do alone: links between the datasets.
🚀 Usage
use FLAIRUK\World\Facades\World;
You can also type-hint FLAIRUK\World\World to have it injected.
Countries and what is in them
A country can be given by its alpha-2 (GB), alpha-3 (GBR) or numeric (826) code, or as a Country object.
World::country('GBR'); // Country, or null World::countryOrFail('GB'); // throws ItemNotFoundException for an unknown code World::citiesIn('GB'); // Collection of City: LON, MAN, EDI, … World::airportsIn('GBR'); // Collection of Airport: LHR, LGW, MAN, … World::airlinesIn(826); // Collection of Airline: BA, VS, …
An unknown country gives an empty collection.
profile() returns all of it at once, as a CountryProfile you can return straight from a controller:
$profile = World::profile('GB'); // CountryProfile, or null $profile->country; // Country $profile->cities; // Collection of City $profile->airports; // Collection of Airport $profile->airlines; // Collection of Airline return $profile; // {"country": {...}, "cities": [...], "airports": [...], "airlines": [...]}
The country of a place
World::countryOf(World::airports()->find('LHR'))->name; // "United Kingdom" World::countryOf(World::cities()->find('LON'))->name; // "United Kingdom" World::countryOf(World::airlines()->find('BA'))->name; // "United Kingdom"
countryOf() returns null for the few airlines with no country.
What a code could mean
Codes overlap between the datasets. code() returns every match for exactly that code, keyed by kind, and leaves out the kinds with no match:
World::code('LHR'); // ['airport' => Airport] World::code('LON'); // ['city' => City] World::code('BA'); // ['country' => Bosnia and Herzegovina, 'airlines' => Collection [British Airways]] World::code('320'); // ['country' => Guatemala (numeric 320), 'aircraft' => Airbus Industrie A320]
The keys are country, city, airport, airlines and aircraft. airlines is a collection, because IATA re-issues designators.
Searching everything
World::search('london'); // ['cities' => [...], 'airports' => [...]] World::search('london', 3); // at most three of each
search() matches each dataset's codes and names, and returns up to ten results per kind (countries, cities, airports, airlines, aircraft), leaving out the kinds with none.
Each dataset
The underlying lookups are available from World too, so one import is enough:
World::countries()->eea(); World::cities()->find('NYC'); World::airports()->search('Heathrow'); World::airlines()->allWithCode('BA'); World::aircraft()->find('388');
These are the same singletons the Countries, Cities, Airports, Airlines and Aircrafts facades use.
💾 Database tables (optional)
To publish all five configs and migrations and then, if you agree, migrate and seed every table:
php artisan world:install # asks before migrating php artisan world:install --migrate # doesn't ask
It skips any migration that an earlier install already published, including one from a dataset's own *:install command, so it is safe to run again.
To update the tables after upgrading the packages:
php artisan world:seed # insert or update every row php artisan world:seed --prune # and delete rows no longer in the data
world:seed runs each dataset's own seed command: countries:seed, cities:seed, airports:seed, airlines:seed and aircrafts:seed. Each table's name and connection are set in that dataset's config file.
🧪 Testing
composer test
📄 License
The MIT License (MIT). See LICENSE for details.