Developing with phone numbers: Validation and formatting

Q: What happens when you allow your users to input data without any kind of normalisation or formatting?

Nick Bishop
Jul 20, 2017 · 4 min read

A: You end up with a steaming pile of crappy data that’s unpredictable and difficult to work with.

I recently came across this issue when I was migrating user’s phone numbers from the first version of Taxi for two to the latest. Some had country codes, some didn’t, others had ‘+’ in front and some I didn’t recognise at all. After wincing at the sight of them and wondering how I could have broken one of the first rules of handling user input when I first wrote the code, I set down to figure out how I would deal with this in the new version.

Phone number formatting

International phone numbers are a pain in the arse. Different countries have different country codes, region codes and different formats. There is little consistency and this makes validation and normalisation very difficult.

So how should we format our phone numbers?

After rooting around on the fantastically useful Stack Overflow I stumbled across references to the E.164 number format. This standardised format describes how international phone numbers should be formatted i.e. (+) + (country code) + (national destination code + subscriber number). Bingo.

Still baffled? Well, if you were from the UK you may recognise this as +447701234567 — where ‘+44’ is the country code for the UK.

Country codes

So we have a format that we want our phone numbers to adhere to. The problem now shifts to the fact that there are literally hundreds of country codes. Also, within each country there are different requirements around format and length. How do we account for all these variations to validate a phone number in the required format?

I turned to Google again. A short time later, Google delivered… in more ways than one. Enter libphonenumber, Google’s phone number handling library. I’m extremely grateful Google decided to get into the mobile OS space with Android. Firstly, it has helped kick phone manufacturer’s butts and teach them what a mobile OS should feel like (yes fanboys, I know Apple helped too). Secondly, it means that great libraries like libphonenumber are open-sourced for us all to use. I digress.

A quick scan down the page and I found that the Java library also has a PHP port (as well as Python and Ruby if you are that way inclined). The library is vast, so there are probably a number of useful classes that I haven’t uncovered yet.

Essentially, you give the library a number and it will parse it into a phone number object, extracting the relevant parts of the phone number in the process. You can then take these objects and do various things, like making sure its a valid phone number. Here’s an example:

$phoneUtil = libphonenumberPhoneNumberUtil::getInstance();
try {
$phoneNumberProto = $phoneUtil -> parse($phoneNumber, $countryCode);
if ($phoneUtil -> isValidNumber($phoneNumberProto)) {
return true;
} else {
return false;
}
}
catch (libphonenumberNumberParseException $e) {
return false;
}

The second argument expects a country code, but this can also be set to null if you are passing in a phone number with the country code already prepended. Once you’ve got the validated phone number you can then do a number of things. Having validated it, I now want to format the number into the E.164 standard:

echo $phoneUtil->format($phoneNumberProto, PhoneNumberFormat::E164);

I know, validation and formatting isn’t that sexy. But like I said at the beginning, its important to ensure user input is validated and normalised so that the data can be used in a consistent, predictable way further down the line. There are also number of other cool things you can do with the library like geocoding the phone number or determining its type e.g. fixed-line, mobile, toll-free.

Frontend special sauce

This is all great for validating and normalizing the phone number ready for storing in the database (or whatever else we want to do with it). However, a problem still remains… how do we ensure that our users know 1) what country code they need to use and 2) the format they are required to put the number in?

We need to provide our users with the ability to input their phone number in an intuitive way. Once again, we could look at using libphonenumber’s helper methods to help us generate the required drop downs and feedback. However, I have also found a nice little jQuery plugin that makes this process very intuitive — bluefieldscom’s international phone input

This plugin creates a drop-down list of international country codes with a picture of the country’s flag. You can set various options such as default country or limiting the countries to a select few. Here’s what it looks like:

We can now be sure that our users have enough cues on how to provide their phone number. This means when the data is posted to our server, it is handed to our libphonenumber class with the country code already prepended so that it can do the normalisation and validation before storing in our database.

Bosh.


Originally published at nickbishop.co.uk.

)

Nick Bishop

Written by

Digital geek. Developer.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade