Search by

ijeffro / laravel-cities

ijeffro

IATA city codes for Laravel: an in-memory lookup API, validation rule and optional database table.

Package info

github.com/FLAIRUK/laravel-cities

pkg:composer/ijeffro/laravel-cities

Statistics

Installs: 8 279

Dependents: 1

Suggesters: 0

Stars: 11

Open Issues: 2

v1.0.0 2026-10-05 09:32 UTC

This package is auto-updated.

Last update: 2026-10-05 11:04:07 UTC


README

Laravel Cities

PHP 8.2+  Laravel 12 or 13  Lint  Tests  Downloads on Packagist  MIT licence  IATA 
 

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 · 🚀 Usage · 💾 Database table · 🔄 Upgrading



📦 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.