Signatur
Beschreibung
Die Klasse Normalizer ist Teil der Intl-Extension und bietet statische Methoden zur Unicode-Normalisierung von Zeichenketten. Unicode erlaubt es, denselben sichtbaren Charakter auf verschiedene Weisen zu kodieren – beispielsweise kann ein Buchstabe mit Akzent als einzelner vorkombinierter Codepunkt oder als Grundbuchstabe gefolgt von einem kombinierenden Zeichen dargestellt werden. Normalizer vereinheitlicht solche Darstellungen.
Die vier Normalisierungsformen unterscheiden sich in ihrer Kompositions- und Kompatibilitätsstrategie: NFC (Canonical Decomposition, followed by Canonical Composition) ist die am häufigsten verwendete Form für Webinhalte und Datenbankfelder. NFD zerlegt Zeichen kanonisch ohne Rekombination. NFKC und NFKD wenden zusätzlich Kompatibilitätszerlegungen an, was typographische Varianten (z. B. Ligaturen, Breitzeichen) normalisiert.
Typische Anwendungsfälle sind der Vergleich von Benutzereingaben, die Normalisierung vor dem Speichern in Datenbanken sowie die Sicherstellung konsistenter Suchergebnisse. Ohne Normalisierung können zwei visuell identische Strings bei strcmp() oder Datenbankabfragen als ungleich gelten.
Die Klasse erfordert die intl-Extension (ab PHP 5.3) und die zugehörige ICU-Bibliothek. Alle Methoden sind statisch; die Klasse wird nicht instanziiert.
Beispiele
Unicode-Zeichenkette in NFC normalisieren
<?php
// 'ä' als zwei Codepunkte: 'a' + kombinierender Umlaut (U+0308)
$decomposed = "a\u{0308}"; // NFD-Form
// Normalisierung in NFC (vorkombinierte Form)
$normalized = Normalizer::normalize($decomposed, Normalizer::FORM_C);
var_dump(strlen($decomposed)); // 3 Bytes (a + 2-Byte-Kombinierer)
var_dump(strlen($normalized)); // 2 Bytes (ä als einzelner Codepunkt)
var_dump($normalized === 'ä'); // bool(true)
Normalisierungsform einer Zeichenkette prüfen
<?php
$string = 'café'; // NFC-kodiert (Standardfall in den meisten Editoren)
if (Normalizer::isNormalized($string, Normalizer::FORM_C)) {
echo "String ist bereits in NFC-Form.\n";
} else {
$string = Normalizer::normalize($string, Normalizer::FORM_C);
echo "String wurde in NFC normalisiert.\n";
}
// Vergleich zweier visuell gleicher, aber unterschiedlich kodierter Strings
$a = "café"; // NFC
$b = "cafe\u{0301}"; // NFD (e + kombinierender Akut)
$aNorm = Normalizer::normalize($a, Normalizer::FORM_C);
$bNorm = Normalizer::normalize($b, Normalizer::FORM_C);
var_dump($aNorm === $bNorm); // bool(true) nach Normalisierung
NFKC für Kompatibilitätsnormalisierung (z. B. Halbbreite/Vollbreite)
<?php
// Japanische Vollbreite-Zeichen (U+FF21 = a)
$fullwidth = "\u{FF41}\u{FF42}\u{FF43}"; // abc
$nfkc = Normalizer::normalize($fullwidth, Normalizer::FORM_KC);
echo $nfkc; // abc (ASCII)
// Wichtig · Fallstricke
Klassen-Konstanten für Normalisierungsformen:
Normalizer::FORM_C/Normalizer::NFC– Kanonische Komposition (empfohlen für Web & Datenbanken)Normalizer::FORM_D/Normalizer::NFD– Kanonische ZerlegungNormalizer::FORM_KC/Normalizer::NFKC– KompatibilitätskompositionNormalizer::FORM_KD/Normalizer::NFKD– Kompatibilitätszerlegung
Fallstricke: Normalizer::normalize() gibt false zurück, wenn der Eingabe-String kein gültiges UTF-8 enthält oder null ist. Es empfiehlt sich daher, den Rückgabewert zu prüfen. Außerdem setzt die Klasse die PHP-Extension intl voraus; fehlt sie, führt jeder Aufruf zu einem fatalen Fehler.
Performance: Normalizer::isNormalized() ist schneller als normalize(), da bei bereits normalisierten Strings keine Transformation nötig ist. In Schleifen mit vielen Strings empfiehlt sich daher die Vorabprüfung.