Een inlogfout die herleid kon worden naar een mismatch in de opslag van telefoonnummers legde een zwakke plek bloot. Het account van een gebruiker werd geblokkeerd omdat de database hetzelfde Duitse mobiele nummer in twee vormen bevatte — 0171 5550134 in de ene rij en +49 171 5550134 in de andere — waardoor het systeem ze als afzonderlijke vermeldingen behandelde. Het resultaat: een OTP kwam nooit aan, en de knop "code verzenden" werd een gokspel.
Waarom telefoonnummers lastiger zijn dan datums
Ontwikkelaars vertrouwen vaak op een regex om telefoonnummerinvoer te temmen. Dat vertrouwen wordt verbrijzeld op het moment dat een nummer een grens overgaat of een nationaal plan verandert. Datums volgen een voorspelbare kalender; telefoonnummers veranderen mee met providers, regelgeving en culturele conventies.
De verborgen kosten van ruwe strings
Het opslaan van een telefoonnummer als een gewone string lijkt uniek — totdat twee weergaven naar dezelfde lijn verwijzen. OTP-systemen die de database bevragen naar "het" nummer, eindigen met het verzenden van een code naar een duplicaat die de gebruiker nooit bereikt.
Het probleem verergert wanneer nummers in numerieke velden staan. Een BIGINT-kolom verwijdert het voorvoegsel + en eventuele voorloopnullen, waardoor +49 171 5550134 verandert in 491715550134. Zonder het plusteken wordt het reconstrueren van het oorspronkelijke formaat een gokwerk.
Het E.164-contract
Het internationale telefoonnummerplan, E.164, definieert een enkele, draagbare weergave:
- Begint met een
+ - Gevolgd door een landcode van 1 tot 3 cijfers
- Daarna het abonnee-nummer
- Maximaal 15 cijfers in totaal
- Geen spaties, punten of streepjes
E.164 garandeert niet dat het nummer actief is; het garandeert alleen dat de string een geldig structureel patroon volgt. Beschouw het als een formaatcontract, niet als een oracle voor bereikbaarheid.
Veelvoorkomende valkuilen die regex niet kan oplossen
- Numerieke opslag –
BIGINTlaat de+en voorloopnullen vallen. Gebruik in plaats daarvan een tekstkolom (TEXTofVARCHAR). - Hard-coded regexes – Nationale plannen veranderen. Mexico schrapte in 2019 zijn trunk-prefix; Argentinië vereist nu een
9na de landcode voor mobiele lijnen. Een statisch patroon raakt snel verouderd. - Blind het verwijderen van nullen – Italiaanse vaste lijnen behouden een voorloopnul, Duitse niet. Een algemene regel "verwijder voorloopnullen" corrumpeert Italiaanse gegevens, terwijl Duitse nummers ongemoeid blijven.
- Aannemen dat formaat gelijkstaat aan leverbaarheid –
libphonenumbervalideert de structuur, maar kan niet zien of de handset aan staat of dat het nummer is gemigreerd.
Het bouwen van een betrouwbare pipeline
- Vraag om een land – Voeg een landenselector toe aan aanmeldformulieren en geef die regio door aan de parser.
- Toon live formattering – Gebruik "AsYouType"-formattering zodat gebruikers het juiste patroon zien terwijl ze typen.
- Valideer bij 'blur' – Voer validatie uit nadat de gebruiker het veld verlaat in plaats van bij elke toetsaanslag; dit vermindert frictie.
- Sla alleen de E.164-string op – Sla het genormaliseerde nummer met het
+-voorvoegsel op in de database. - Formatteer aan de rand – Converteer pas terug naar een mensvriendelijke lay-out in de UI of e-mailtemplates.
Bewaar bij het migreren van legacy-gegevens de rijen die de validatie niet doorstaan. Parse elke bestaande vermelding naar een nieuwe kolom, markeer de fouten en genereer een rapport. Stille gegevensverliezen leiden tot supporttickets die later uitmonden in kostbare reparaties.
Een snelle checklist voor ontwikkelaars
- Sla nummers op als
TEXT/VARCHARin E.164-formaat. - Gebruik de libphonenumber-bibliotheek van Google; deze gaat om met de rommelige realiteit van wereldwijde plannen.
- Bied een standaardregio aan voor gebruikers die de landcode weglaten.
- Roep
is_valid_numberaan voor live aanmeldingen; dit controleert of het nummer voldoet aan de regionale regels. - Gebruik
is_possible_numberbij het opschonen van bulkgegevens; dit vangt overduidelijk foutieve vermeldingen op zonder grensgevallen af te wijzen.
Goede afhandeling van telefoonnummers is geen luxe; het is een vereiste voor elk systeem dat afhankelijk is van betrouwbaar gebruikerscontact. Door te normaliseren naar E.164 en het parsen uit te besteden aan een bewezen bibliotheek, elimineren ontwikkelaars een hele klasse bugs die stilletjes het vertrouwen en de omzet uithollen. Behandel telefoonnummers als gestructureerde gegevens, niet als vrije tekst, en laat de standaarden het zware werk doen.
