php 55 lines · 8 steps

Normalizing human names in PHP

A small class that cleans, keys, and title-cases personal names while respecting Unicode and naming particles.

Explained by highlit
1<?php
2 
3declare(strict_types=1);
4 
5namespace App\Support;
6 
7use Normalizer;
8 
9final class NameNormalizer
10{
11 private const PARTICLES = ['de', 'la', 'van', 'von', 'der', 'den', 'del', 'di', 'da', 'du', 'le'];
12 
13 public function normalize(string $name): string
14 {
15 $name = Normalizer::normalize($name, Normalizer::FORM_C) ?: $name;
16 $name = $this->transliterate($name);
17 
18 $name = mb_strtolower(trim($name), 'UTF-8');
19 $name = preg_replace('/[\x{2018}\x{2019}\x{201C}\x{201D}]/u', "'", $name);
20 $name = preg_replace('/[^\p{L}\p{N}\s\'-]/u', ' ', $name);
21 $name = preg_replace('/\s+/u', ' ', trim($name));
22 
23 return $name;
24 }
25 
26 public function lookupKey(string $name): string
27 {
28 return str_replace([' ', '-', "'"], '', $this->normalize($name));
29 }
30 
31 public function canonicalDisplay(string $name): string
32 {
33 $parts = explode(' ', $this->normalize($name));
34 
35 $parts = array_map(function (string $part): string {
36 if (in_array($part, self::PARTICLES, true)) {
37 return $part;
38 }
39 
40 return implode('-', array_map(
41 static fn (string $seg): string => mb_convert_case($seg, MB_CASE_TITLE, 'UTF-8'),
42 explode('-', $part)
43 ));
44 }, $parts);
45 
46 return implode(' ', $parts);
47 }
48 
49 private function transliterate(string $value): string
50 {
51 $ascii = transliterator_transliterate('Any-Latin; Latin-ASCII; [\u0080-\u7fff] remove', $value);
52 
53 return $ascii !== false ? $ascii : $value;
54 }
55}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Unicode normalization plus transliteration turns visually identical but differently-encoded names into one comparable form.
  2. 2Separating a lookup key from a display form lets you match loosely while still presenting names nicely.
  3. 3Name capitalization needs domain rules — lowercase particles like 'van' and 'de' shouldn't be title-cased.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Normalizing human names in PHP — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code