Looking to hire Laravel developers? Try LaraJobs

laravel-cities maintained by flairuk

Description
IATA city codes for Laravel: an in-memory lookup API, validation rule and optional database table.
Author
Last update
2026/10/05 13:04 (dev-main)
License
Downloads
100

Comments
comments powered by Disqus

Laravel Cities — More than 9,000 IATA city codes (LON, NYC, PAR, …) for Laravel 12 and 13. In IATA's scheme a city code groups the airports that serve a city, as LON does for Heathrow, Gatwick and Stansted. This package lists the city codes; it does not map them to airports.

  • No database required. Look cities up through a facade backed by an in-memory dataset.
  • Typed results. Every lookup returns readonly City objects in Laravel collections keyed by code.
  • Validation rule. new CityCode accepts known codes only.
  • Optional table. Publish a migration and seed a cities table when other tables need to reference cities.

📦 Installation

composer require flairuk/laravel-cities

Requires PHP 8.2 or later with Laravel 12, or PHP 8.3 or later with Laravel 13.

Laravel discovers the service provider and the Cities facade automatically.

🚀 Usage

use FLAIRUK\Cities\Facades\Cities;

Cities::find('lon');             // City { id: 4241, code: "LON", name: "London", countryCode: "GB" }
Cities::findOrFail('LON');       // throws ItemNotFoundException for unknown codes
Cities::exists('NYC');           // true
Cities::findById(4241);

Cities::all();                   // Collection<string, City> keyed by code
Cities::inCountry('FR');         // cities in France
Cities::search('london');        // matches on name or exact code
Cities::codes();

Select options

Cities::options();               // ['LON' => 'London', ...] sorted by name
Cities::options('id');           // [4241 => 'London', ...]

Validation

use FLAIRUK\Cities\Rules\CityCode;

$request->validate(['city' => ['required', new CityCode]]);

💾 Database table (optional)

php artisan cities:install             # publish config + migration, then ask to migrate and seed
php artisan cities:install --migrate   # migrate and seed without asking
php artisan cities:seed            # insert / update (safe to re-run)
php artisan cities:seed --prune    # also delete rows no longer in the dataset

You can also call the seeder from your own DatabaseSeeder:

$this->call(\FLAIRUK\Cities\Database\CitiesSeeder::class);

Query the table through the bundled Eloquent model:

use FLAIRUK\Cities\Models\City;

City::code('LON')->first();
City::inCountry('GB')->orderBy('name')->get();

The table name and connection come from CITIES_TABLE and CITIES_DB_CONNECTION, or from the published config.

🔄 Upgrading from dev-master

Version 1.0 is a rewrite. Breaking changes:

dev-master 1.0
Package ijeffro/laravel-cities flairuk/laravel-cities
ijeffro\Cities\… namespace FLAIRUK\Cities\…
Facade ijeffro\Cities\CitiesFacade FLAIRUK\Cities\Facades\Cities (auto-discovered)
Cities::getList($sort) (array) Cities::all()->sortBy($property, SORT_NATURAL | SORT_FLAG_CASE) (Collection of City; properties are camelCase, e.g. countryCode)
Cities::getOne($id) Cities::findById($id) or Cities::find($code)
Cities::getListForSelect() (keyed by id) Cities::options('id')
php artisan cities:migration php artisan cities:install / cities:seed
Config key cities.table_name cities.table
Field / column iso_3166_3 code. It was always an IATA city code, not an ISO 3166 code

Row ids are unchanged. If you have an existing table, rename the column before re-seeding:

Schema::table('cities', fn (Blueprint $table) => $table->renameColumn('iso_3166_3', 'code'));

🧪 Testing

composer test

📄 License

MIT. See LICENSE.