Pragmatism in the real world

Validating UK Postcodes

I’m sure everyone else already knows this, but I’ve recently discovered that Zend_Validate_PostCode doesn’t work with UK postcodes unless you first remove the space between the first and second parts. This is due to a bug in the underlying regular expresssions that are provided by CLDR.

It’s easy enough to add a filter to remove the space, but I’m a little worried that when (and if) it gets fixed, will the fixed version Zend_Validate_PostCode then fail to validate postcodes without the space? In theory it should as the space is part of the spec. I’d hate my code to unexpectedly break due to a valid bug fix.

I can easy work around this worry though by simply creating my own extension of Zend_Validate_PostCode, so that’s what I did:

library/App/Validate/PostCode.php:
<?php

/**
* @see Zend_Validate_PostCode
*/
require_once 'Zend/Validate/PostCode.php';

class App_Validate_PostCode extends Zend_Validate_PostCode
{
public function isValid($value)
{
$this->_setValue($value);
if (!is_string($value) && !is_int($value)) {
$this->_error(self::INVALID);
return false;
}

if ($this->getLocale() == 'en_GB') {
// From PEAR's Validate_UK - http://pear.php.net/package/Validate_UK
$value = strtoupper(str_replace(' ', '', $value));
$format = "/^([A-PR-UWYZ]([0-9]([0-9]|[A-HJKSTUW])?|[A-HK-Y][0-9]"
. "([0-9]|[ABEHMNPRVWXY])?)[0-9][ABD-HJLNP-UW-Z]{2}|GIR0AA)$/";
} else {
$format = $this->getFormat();
}

if (!preg_match($format, $value)) {
$this->_error(self::NO_MATCH);
return false;
}

return true;
}
}

And of course, with the benefit of ZF’s plugin loader system, once I’m happy that the bug is fixed in Zend_Validate_PostCode, I’ll be able to just remove my override and Zend_Form will carry on working.

Another option is to use Paul Court’s Pmc_Postcode_Validate which has also been written to the UK spec.