PHPackages                             vasildakov/postcode - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. vasildakov/postcode

ActiveLibrary

vasildakov/postcode
===================

UK Postcode ValueObject

1.3(2y ago)3333.8k↓20.4%4[1 issues](https://github.com/vasildakov/postcode/issues)[2 PRs](https://github.com/vasildakov/postcode/pulls)1MITPHPPHP &gt;=8.1

Since Dec 29Pushed 2y ago2 watchersCompare

[ Source](https://github.com/vasildakov/postcode)[ Packagist](https://packagist.org/packages/vasildakov/postcode)[ Docs](https://github.com/vasildakov/postcode)[ RSS](/packages/vasildakov-postcode/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (9)Versions (7)Used By (1)

UK Postcode ValueObject
=======================

[](#uk-postcode-valueobject)

[![Build Status](https://github.com/vasildakov/postcode/workflows/build/badge.svg)](https://github.com/vasildakov/postcode/actions)[![Coverage Status](https://camo.githubusercontent.com/bf5730ea78c0014c262669eb2f8547ad76b65e5014cbe3e2d7363dbf4c6aec7b/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f766173696c64616b6f762f706f7374636f64652f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/vasildakov/postcode?branch=master)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/6a452e1e13ca39658f64d077557be56844ae10096cae93961df25ec0b97db339/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f766173696c64616b6f762f706f7374636f64652f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/vasildakov/postcode/?branch=master)[![Packagist Version](https://camo.githubusercontent.com/73461632d735a18c7cb9ee31ee59ad72384ca09f283015a03e6526c590e73472/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f766173696c64616b6f762f706f7374636f6465)](https://packagist.org/packages/vasildakov/postcode)[![Total Downloads](https://camo.githubusercontent.com/414091008569306f4871e788cd7360f91cad053ea92271f0cd90fd009cf33921/68747470733a2f2f706f7365722e707567782e6f72672f766173696c64616b6f762f706f7374636f64652f646f776e6c6f616473)](https://packagist.org/packages/vasildakov/postcode)[![Packagist Dependency Version](https://camo.githubusercontent.com/65d6f51ff305918c1313f493691eb55c382b09dcef768cd15fc56aeb8c89ab55/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646570656e64656e63792d762f766173696c64616b6f762f706f7374636f64652f706870)](https://camo.githubusercontent.com/65d6f51ff305918c1313f493691eb55c382b09dcef768cd15fc56aeb8c89ab55/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646570656e64656e63792d762f766173696c64616b6f762f706f7374636f64652f706870)[![License](https://camo.githubusercontent.com/c8f1ff9739e36022542833fa6d0d9854564e0f673192e51f28802f3344b19b31/68747470733a2f2f706f7365722e707567782e6f72672f766173696c64616b6f762f706f7374636f64652f6c6963656e7365)](https://packagist.org/packages/vasildakov/postcode)

Synopsis
--------

[](#synopsis)

[Value Object](http://martinfowler.com/bliki/ValueObject.html) that represents an UK postcode

Installation
------------

[](#installation)

Here is a minimal example of a `composer.json` file that just defines a dependency on Postcode:

```
{
    "require": {
        "vasildakov/postcode": "^1.1"
    }
}

```

Code Example
------------

[](#code-example)

#### Creating a Postcode object

[](#creating-a-postcode-object)

```
use VasilDakov\Postcode\Postcode;

// Create a Postcode
$postcode = new Postcode('EC1V 9LB');

// Validate Postcode value
print $postcode->valid();
```

#### Perform simple validations, parsing and normalisation

[](#perform-simple-validations-parsing-and-normalisation)

```
$postcode->normalise()    // => "EC1V 9LB"

$postcode->outcode()      // => "EC1V"
$postcode->incode()       // => "9LB"
$postcode->area()         // => "EC"
$postcode->district()     // => "EC1"
$postcode->subdistrict()  // => "EC1V"
$postcode->sector()       // => "EC1V 9"
$postcode->unit()         // => "LB"
```

### Method Overview

[](#method-overview)

Postcodeoutcode()incode()area()district()subdistrict()sector()unit()AA9A 9AAAA9A9AAAAAA9AA9AAA9A 9AAA9A 9AAA9A9AAAA9A9AA9A 9AAA9 9AAA99AAAA9nullA9 9AAA99 9AAA999AAAA99nullA99 9AAAA9 9AAAA99AAAAAA9nullAA9 9AAAA99 9AAAA999AAAAAA99nullAA99 9AADefinitions
-----------

[](#definitions)

### Outcode

[](#outcode)

The outward code is the part of the postcode before the single space in the middle. It is between two and four characters long. A few outward codes are non-geographic, not divulging where mail is to be sent. Examples of outward codes include "L1", "W1A", "RH1", "RH10" or "SE1P".

### Incode

[](#incode)

The inward part is the part of the postcode after the single space in the middle. It is three characters long. The inward code assists in the delivery of post within a postal district. Examples of inward codes include "0NY", "7GZ", "7HF", or "8JQ".

### Area

[](#area)

The postcode area is part of the outward code. The postcode area is between one and two characters long and is all letters. Examples of postcode areas include "L" for Liverpool, "RH" for Redhill and "EH" Edinburgh. A postal area may cover a wide area, for example "RH" covers north Sussex, (which has little to do with Redhill historically apart from the railway links), and "BT" (Belfast) covers the whole of Northern Ireland.

### District

[](#district)

The district code is part of the outward code. It is between two and four characters long. It does not include the trailing letter found in some outcodes. Examples of district codes include "L1", "W1", "RH1", "RH10" or "SE1".

### Sub-District

[](#sub-district)

The sub-district code is part of the outward code. It is often not present, only existing in particularly high density London districts. It is between three and four characters long. It does include the trailing letter omitted from the district. Examples of sub-district codes include "W1A", "EC1A", "NW1W", "E1W" or "SE1P".

### Sector

[](#sector)

The postcode sector is made up of the postcode district, the single space, and the first character of the inward code. It is between four and six characters long (including the single space). Examples of postcode sectors include "SW1W 0", "PO16 7", "GU16 7", or "L1 8", "CV1 4".

### Unit

[](#unit)

The postcode unit is two characters added to the end of the postcode sector. Each postcode unit generally represents a street, part of a street, a single address, a group of properties, a single property, a sub-section of the property, an individual organisation or (for instance Driver and Vehicle Licensing Agency) a subsection of the organisation. The level of discrimination is often based on the amount of mail received by the premises or business. Examples of postcode units include "NY" (from "SW1W 0NY"), "GZ" (from "PO16 7GZ"), "HF" (from "GU16 7HF"), or "JQ" (from "L1 8JQ").

Sources:

- [https://en.wikipedia.org/wiki/Postcodes\_in\_the\_United\_Kingdom#Formatting](https://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom#Formatting)
- [https://en.wikipedia.org/wiki/London\_postal\_district#Numbered\_divisions](https://en.wikipedia.org/wiki/London_postal_district#Numbered_divisions)

Note on Postcode Validation
---------------------------

[](#note-on-postcode-validation)

Postcodes cannot be validated just with a regular expression. Proper postcode validation requires having a full list of postcodes to check against. Relying on a regex will produce false postives/negatives.

A complete list of Postcodes can be obtained from the ONS Postcode Directory, which is updated every 3 months.

License
-------

[](#license)

Code released under [the MIT license](https://github.com/vasildakov/postcode/blob/master/LICENSE)

###  Health Score

35

—

LowBetter than 80% of packages

Maintenance13

Infrequent updates — may be unmaintained

Popularity39

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity59

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~182 days

Total

3

Last Release

871d ago

PHP version history (2 changes)1.1PHP &gt;=5.4

1.2PHP &gt;=8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/1fc1adf79e7d98dffd7af89ec2018c2cfb6c2971ffec7d9a81c437d8074b2c50?d=identicon)[vasildakov](/maintainers/vasildakov)

---

Top Contributors

[![vasildakov](https://avatars.githubusercontent.com/u/97174920?v=4)](https://github.com/vasildakov "vasildakov (60 commits)")

---

Tags

phppostcodeukvalue-objectphppostcodepostuk

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/vasildakov-postcode/health.svg)

```
[![Health](https://phpackages.com/badges/vasildakov-postcode/health.svg)](https://phpackages.com/packages/vasildakov-postcode)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
