jessebyarugaba/ug-address

Cascading Uganda address selector — District → County → Sub-county → Parish → Village

Maintainers

Package info

github.com/jessebyarugaba/ug-address-php

pkg:composer/jessebyarugaba/ug-address

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.0 2026-05-20 21:09 UTC

This package is not auto-updated.

Last update: 2026-05-21 19:39:04 UTC


README

A lightweight PHP SDK for cascading Uganda address selection.

Supports:

District → County/Division → Sub-county → Parish → Village

The SDK is:

  • dependency-free
  • offline-first
  • framework agnostic
  • fast
  • pure PHP

Perfect for:

  • Laravel
  • Symfony
  • CodeIgniter
  • Slim
  • custom PHP projects
  • fintech onboarding
  • delivery systems
  • registration forms
  • Uganda-based SaaS products

Installation

Install via Composer:

composer require jessebyarugaba/ug-address

Quick Start

<?php

require_once 'vendor/autoload.php';

use UgAddress\UgAddress;

$addr = new UgAddress();

$districts = $addr->getDistricts();

print_r($districts);

Example Output

Array
(
    [0] => Array
        (
            [id] => 98
            [name] => ABIM
        )

    [1] => Array
        (
            [id] => 1
            [name] => ADJUMANI
        )
)

Full Example

<?php

require_once 'vendor/autoload.php';

use UgAddress\UgAddress;

$addr = new UgAddress();

# -----------------------------------
# Get districts
# -----------------------------------

$districts = $addr->getDistricts();

echo "DISTRICTS:\n\n";

foreach (array_slice($districts, 0, 5) as $district) {

    echo $district['id']
        . ' - '
        . $district['name']
        . PHP_EOL;
}

# -----------------------------------
# Select district
# -----------------------------------

$addr->selectDistrict('32'); // Kampala

$counties = $addr->getCounties();

echo "\nCOUNTIES:\n\n";

foreach ($counties as $county) {

    echo $county['id']
        . ' - '
        . $county['name']
        . PHP_EOL;
}

# -----------------------------------
# Select county
# -----------------------------------

$addr->selectCounty($counties[0]['id']);

$subcounties = $addr->getSubcounties();

echo "\nSUBCOUNTIES:\n\n";

foreach (array_slice($subcounties, 0, 5) as $subcounty) {

    echo $subcounty['id']
        . ' - '
        . $subcounty['name']
        . PHP_EOL;
}

# -----------------------------------
# Select subcounty
# -----------------------------------

$addr->selectSubcounty($subcounties[0]['id']);

$parishes = $addr->getParishes();

echo "\nPARISHES:\n\n";

foreach (array_slice($parishes, 0, 5) as $parish) {

    echo $parish['id']
        . ' - '
        . $parish['name']
        . PHP_EOL;
}

# -----------------------------------
# Select parish
# -----------------------------------

$addr->selectParish($parishes[0]['id']);

$villages = $addr->getVillages();

echo "\nVILLAGES:\n\n";

foreach (array_slice($villages, 0, 5) as $village) {

    echo $village['id']
        . ' - '
        . $village['name']
        . PHP_EOL;
}

# -----------------------------------
# Select village
# -----------------------------------

$addr->selectVillage($villages[0]['id']);

# -----------------------------------
# Final address
# -----------------------------------

echo "\nFORMATTED ADDRESS:\n\n";

echo $addr->getFormattedAddress();

echo "\n\n";

# -----------------------------------
# Raw selection
# -----------------------------------

echo "RAW SELECTION:\n\n";

print_r(
    $addr->getSelection()
);

API Reference

Constructor

use UgAddress\UgAddress;

$addr = new UgAddress();

Data Getters

All getters return alphabetically sorted arrays.

getDistricts()

Returns all Uganda districts.

$districts = $addr->getDistricts();

getCounties($districtId = null)

Returns counties/divisions for a district.

$counties = $addr->getCounties('32');

If no ID is provided, the currently selected district is used.

getSubcounties($countyId = null)

Returns sub-counties for a county.

$subcounties = $addr->getSubcounties('69');

getParishes($subcountyId = null)

Returns parishes for a sub-county.

$parishes = $addr->getParishes('1546');

getVillages($parishId = null)

Returns villages/cells for a parish.

$villages = $addr->getVillages('9127');

Selection Methods

Selecting a level automatically clears downstream selections.

selectDistrict($id)

$addr->selectDistrict('32');

selectCounty($id)

$addr->selectCounty('69');

selectSubcounty($id)

$addr->selectSubcounty('1546');

selectParish($id)

$addr->selectParish('9127');

selectVillage($id)

$addr->selectVillage('57217');

Event Listeners

The SDK supports reactive callbacks.

onDistrictChange()

$addr->onDistrictChange(function ($e) {

    print_r($e);

});

Event structure:

[
    'districtId' => '32',
    'counties'   => [...]
]

onCountyChange()

$addr->onCountyChange(function ($e) {

    print_r($e);

});

onSubcountyChange()

$addr->onSubcountyChange(function ($e) {

    print_r($e);

});

onParishChange()

$addr->onParishChange(function ($e) {

    print_r($e);

});

onVillageChange()

$addr->onVillageChange(function ($e) {

    print_r($e);

});

Reading the Selection

getSelection()

Returns the currently selected hierarchy.

$selection = $addr->getSelection();

Example:

[
    'district' => [
        'id'   => '32',
        'name' => 'KAMPALA'
    ],

    'county' => [
        'id'   => '69',
        'name' => 'KAMPALA CENTRAL DIVISION'
    ],

    'subcounty' => [
        'id'   => '123',
        'name' => 'CENTRAL WARD'
    ],

    'parish' => [
        'id'   => '456',
        'name' => 'NAKASERO PARISH'
    ],

    'village' => [
        'id'   => '789',
        'name' => 'NAKASERO VILLAGE A'
    ]
]

getFormattedAddress()

Returns a human-readable address string.

echo $addr->getFormattedAddress();

Example:

Nakasero Village A, Nakasero Parish, Central Ward, Kampala Central Division, Kampala

Direct Lookup Helpers

findDistrict()

$district = $addr->findDistrict('32');

findCounty()

$county = $addr->findCounty('69');

findSubcounty()

$subcounty = $addr->findSubcounty('1546');

findParish()

$parish = $addr->findParish('9127');

findVillage()

$village = $addr->findVillage('57217');

Reset

reset()

Clears all selected levels.

$addr->reset();

Laravel Example

<?php

use UgAddress\UgAddress;

Route::get('/districts', function () {

    $addr = new UgAddress();

    return response()->json(
        $addr->getDistricts()
    );

});

Data Structure

District
└── County / Division
    └── Sub-county
        └── Parish
            └── Village / Cell

Relationships:

county.district === district.id
subcounty.county === county.id
parish.subcounty === subcounty.id
village.parish === parish.id

Performance

The SDK ships with embedded Uganda administrative data:

  • no API requests
  • no database needed
  • works fully offline

Use Cases

  • Uganda registration forms
  • Backend address validation
  • Delivery systems
  • CRM systems
  • Fintech onboarding
  • Logistics platforms
  • Government systems
  • Health systems
  • E-commerce platforms

License

MIT License

Free for:

  • commercial use
  • SaaS products
  • government systems
  • educational projects
  • open-source projects

Links