Navigation
 Startseite
 Fachbücher
 Anzeigenmarkt
 Forum
 Webmaster News
 Script Newsletter
 Kontakt
 Script Installation
 Php
 Php Tutorials
 Lernpfade
 Webhoster Vergleich
 Impressum

Community-Bereich
 kostenlos Registrieren
 Anmelden
 Benutzerliste

Script Datenbank
 Script Archiv
 Script Top 20
 Screenshots
 Testberichte

Suche
 

Unsere Php Scripts
 Counter Script
 Umfrage Script
 Bilder Upload Script
 Terminverwaltung
 Simple PHP Forum
 RSS Grabber

Tools und Generatoren
 .htpasswd Generator
 md5 Generator
 base64 Generator
 Markdown to HTML
 Colorpicker
 Unix timestamp Tool
 Unit Test Generator
 TLD Liste
 Webkatalog‑Verzeichnis

Hosterplus.de
Bekommen Sie Speicherplatz (Webspace), Domains und...
https://www.Hosterplus.de
Artfiles.de
Bietet Serviceorientierte Internetdienstleistungen...
https://www.Artfiles.de
 
 
 

PHP transliterator_transliterate(): Umschrift und Slugs

Sie befinden sich: Home > Php Tutorial > PHP transliterator_translit...

PHP transliterator_transliterate(): Umschrift und Slugs
Eintrag am:
10.08.2026
Hits / Besucher:
3
Sprache:
  Deutsch
Tutorial Art:
eigenes
Eingetragen von:
Merkliste:
 
Beschreibung

Ein Reisebericht heißt "Ein Wochenende in Θεσσαλονίκη", und die selbstgebaute Ersetzungsliste im Projekt kennt nur deutsche Umlaute. In der URL landet ein-wochenende-in-, der Rest verschwindet spurlos. Genau hier hilft PHP transliterator_transliterate: die Funktion schreibt jede Schrift ins lateinische Alphabet um, ohne dass irgendjemand eine Zeichentabelle pflegen muss. Aus dem Titel oben wird damit ein-wochenende-in-thessalonike.

Illustration zum Tutorial: PHP transliterator_transliterate(): Umschrift und Slugs

Das Bild zeigt den Weg von den fremden Zeichen durch die zwei Regelstufen bis zum fertigen Slug. Diesem Weg folgt auch der Text, angefangen bei der Frage, was die Funktion überhaupt verspricht.

Was PHP transliterator_transliterate() macht

Der Aufruf braucht zwei Angaben: eine Regel-Kennung und den Text. Heraus kommt der umgeschriebene Text. PHP transliterator_transliterate stammt aus der intl-Erweiterung und setzt auf ICU auf, also auf dieselbe Bibliothek, die auch Datumsformate und Sortierreihenfolgen liefert. Die Regeln stecken deshalb nicht in PHP, sondern in ICU. Wie viele es sind, verrät Transliterator::listIDs(): auf ICU 76.1 sind es 756 Kennungen.

<?php

$text = 'Привет, мир';

echo transliterator_transliterate('Any-Latin; Latin-ASCII', $text);
/* Privet, mir */

/* Die Sprache bleibt Russisch, nur die Schrift wechselt.
Uebersetzt hat hier niemand etwas. */

Die Signatur hat vier Parameter, die beiden hinteren grenzen den bearbeiteten Bereich ein. Sie rechnen in UTF-16-Codeeinheiten, nicht in Bytes und nicht in Zeichen: $start inklusive, $end exklusive.

transliterator_transliterate(

Transliterator|string $transliterator,
string $string,
int $start = 0,
int $end = -1
): string|false
<?php

/* Nur die ersten sechs UTF-16-Codeeinheiten umschreiben.
'Привет' belegt genau sechs davon, das Leerzeichen
und das zweite Wort bleiben stehen. */
var_dump(transliterator_transliterate(
'Any-Latin; Latin-ASCII',
'Привет мир',
0,
6
));
/* string(13) "Privet мир" */

Der erste Parameter nimmt entweder eine Kennung als Zeichenkette oder ein fertiges Transliterator-Objekt, beides ist gleichwertig. Im Fehlerfall gibt PHP transliterator_transliterate den Wert false aus, nicht null und nicht eine leere Zeichenkette.

Umschrift ist keine Übersetzung und keine Kodierung

Transliteration wechselt die Schrift, nicht die Sprache. Aus Привет wird Privet, und das Wort bedeutet unverändert "Hallo". Übersetzt hat niemand etwas, es steht nur in anderen Buchstaben da. Wer den Begriff zum ersten Mal liest, hat damit schon das Wesentliche.

Genauso wenig ist Transliteration eine Kodierung. Eine Kodierung legt fest, aus welchen Bytes ein Zeichen im Speicher besteht, und lässt das Zeichen selbst in Ruhe. Hier passiert das Gegenteil: das Zeichen wird ersetzt. Daran hängt die Arbeitsteilung zu einem Nachbarthema. Die mb_*-Funktionen arbeiten mit Mehrbyte-Zeichen, ohne sie anzutasten. PHP transliterator_transliterate tastet sie ausdrücklich an und schreibt sie in eine andere Schrift um. Wie Länge, Schnitt und Kodierung solcher Zeichen sauber behandelt werden, steht im Tutorial zu den Multibyte-Strings in PHP. Gebraucht wird die Umschrift überall dort, wo ein System nur lateinische Buchstaben annimmt: in URLs, in Dateinamen auf einem Windows-Server, in Sortier- und Suchspalten.

Die Regel-Kette Any-Latin und Latin-ASCII

Regeln werden mit Semikolon verkettet und von links nach rechts angewendet. Any-Latin bringt eine beliebige Schrift ins lateinische Alphabet, lässt dabei aber Akzente, Häkchen und Striche stehen. Latin-ASCII räumt genau diese Diakritika ab. Warum PHP transliterator_transliterate beide Glieder braucht, zeigt sich am besten, wenn jedes einzeln läuft.

<?php

$ort = 'Ярославль';

/* Nur Latin-ASCII: passiert gar nichts.
Die Regel kennt Kyrillisch nicht. */
echo transliterator_transliterate('Latin-ASCII', $ort);
/* Ярославль */

/* Nur Any-Latin: lateinisch, aber mit Diakritika */
echo transliterator_transliterate('Any-Latin', $ort);
/* Âroslavlʹ */

/* Beide zusammen: das gewuenschte Ergebnis */
echo transliterator_transliterate('Any-Latin; Latin-ASCII', $ort);
/* Aroslavl' */

Der erste Aufruf ist der Beweis. Latin-ASCII allein lässt kyrillischen und griechischen Text liegen, weil die Regel nur lateinische Zeichen kennt. Ein drittes Glied ist oft nützlich: Lower schreibt klein und ist dabei multibyte-sicher. Die Tabelle stellt die wichtigsten Kennungen samt gemessenem Ergebnis nebeneinander.

Regel Wirkung Beispiel Ergebnis
Any-Latin Bringt jede Schrift ins lateinische Alphabet, Diakritika bleiben Ярославль Âroslavlʹ
Latin-ASCII Räumt Diakritika ab, lässt fremde Schriften unangetastet Âroslavlʹ Aroslavl'
Any-Latin; Latin-ASCII Das Arbeitspferd, beide Stufen nacheinander Ελληνικά Ellenika
Lower Kleinschreibung, im Gegensatz zu strtolower() multibyte-sicher ÄRGER ärger
Russian-Latin/BGN Russisch nach BGN-Standard, Zischlaute bleiben erhalten Щёкино Shchekino
Greek-Latin/UNGEGN Neugriechische statt klassischer Umschrift Αθήνα Athina
NFD Zerlegt Zeichen in Grundzeichen plus Akzent, sichtbar erst mit einer Remove-Regel Dvořák Ångström Dvorak Angstrom

Die letzten drei Zeilen deuten an, wie viel an der Kennung hängt, die PHP transliterator_transliterate bekommt: sie legt fest, welche Zeichen überhaupt angefasst werden. Wie groß der Unterschied ausfällt, zeigt der Vergleich mehrerer Schriften.

Kyrillisch, Griechisch, Arabisch und Chinesisch im Vergleich

Vier Schriften laufen durch PHP transliterator_transliterate, eine Regel-Kette, vier gemessene Ergebnisse. An der arabischen Zeile hängt eine Erkenntnis, die der Regelname verschweigt.

<?php

$regel = 'Any-Latin; Latin-ASCII';

echo transliterator_transliterate($regel, 'Привет, мир');
/* Privet, mir */

echo transliterator_transliterate($regel, 'Ελληνικά');
/* Ellenika */

echo transliterator_transliterate($regel, 'مرحبا بالعالم');
/* mrhba balʿalm */

echo transliterator_transliterate($regel, '北京大学');
/* bei jing da xue */

/* Achtung beim arabischen Ergebnis: das Zeichen ʿ ist
U+02BF und ueberlebt Latin-ASCII unveraendert. Der
Name der Regel verspricht mehr, als sie haelt. */

Reines ASCII liefert PHP transliterator_transliterate also nicht, obwohl die Kennung es nahelegt. Ein Test mit preg_match('/^[\x00-\x7F]*$/', $ergebnis) fällt bei der arabischen Zeile durch. Auch und £ bleiben stehen, während © zu (C) wird, ½ zu 1/2 und die Auslassungspunkte zu drei Punkten. Wer garantiertes ASCII braucht, prüft selbst nach oder verlässt sich auf den Slug-Filter weiter unten.

Der zweite Punkt wiegt schwerer und ist der größte Qualitätsgewinn im ganzen Thema. Any-Latin liefert eine wissenschaftliche Umschrift, keine, die ein deutscher oder englischer Leser erwartet. Bei bekannter Ausgangssprache gibt es Besseres.

<?php

$ort = 'Ярославль Щёкино';

/* Generisch: das Щ verliert seinen Klang komplett */
echo transliterator_transliterate('Any-Latin; Latin-ASCII', $ort);
/* Aroslavl' Sekino */

/* Mit der Regel fuer Russisch nach BGN-Standard */
echo transliterator_transliterate(
'Russian-Latin/BGN; Latin-ASCII',
$ort
);
/* Yaroslavl' Shchekino */

/* Dasselbe bei Griechisch: klassisch gegen neugriechisch */
$griechisch = 'Ελληνικά Νέα Αθήνα';

echo transliterator_transliterate('Any-Latin; Latin-ASCII', $griechisch);
/* Ellenika Nea Athena */

echo transliterator_transliterate(
'Greek-Latin/UNGEGN; Latin-ASCII',
$griechisch
);
/* Ellinika Nea Athina */

Aus Щёкино macht die generische Kette das unlesbare Sekino, weil Any-Latin zuerst Ŝëkino erzeugt und Latin-ASCII das Dach danach ersatzlos streicht. Die BGN-Regel kommt auf Shchekino, und das ist die Schreibweise, die ein Leser wiedererkennt. Wer die Ausgangssprache seiner Daten kennt, teilt sie PHP transliterator_transliterate also mit. Any-Latin bleibt der Notnagel für Eingaben, bei denen niemand weiß, was kommt.

Die Umlaut-Falle bei PHP transliterator_transliterate()

Jetzt der Punkt, an dem deutschsprachige Projekte reihenweise stolpern. Latin-ASCII folgt keiner Landeskonvention. Die Regel entfernt Punkte und Striche über den Buchstaben, mehr nicht. Aus ä wird deshalb ein a und kein ae, aus ö ein o, aus ü ein u. Einzige Ausnahme ist das Eszett, das zu ss wird, und sie verleitet zu dem Fehlschluss, die Regel kenne deutsche Gepflogenheiten.

<?php

$regel = 'Any-Latin; Latin-ASCII';

/* So NICHT, wenn deutsche Konvention gefragt ist */
echo transliterator_transliterate($regel, 'Grüße aus Köln');
/* Grusse aus Koln */

echo transliterator_transliterate($regel, 'Öl Ärger Übung Straße');
/* Ol Arger Ubung Strasse */

/* Richtig: die Umlaute VORHER selbst ersetzen */
$umlaute = [
'ä' => 'ae', 'ö' => 'oe', 'ü' => 'ue',
'Ä' => 'Ae', 'Ö' => 'Oe', 'Ü' => 'Ue',
'ß' => 'ss',
];

$eingabe = 'Grüße aus Köln, Müller & Söhne';
$vorbereitet = strtr($eingabe, $umlaute);

echo transliterator_transliterate($regel, $vorbereitet);
/* Gruesse aus Koeln, Mueller & Soehne */

Sieben Einträge in einer Austauschliste genügen, und das Ergebnis läuft danach unverändert durch die Umschrift, weil ae, oe, ue und ss bereits ASCII sind. Wie strtr() mit einer Austauschliste arbeitet, steht im eigenen Tutorial.

Entscheidend ist die Reihenfolge. Der Ersatz muss vor dem Aufruf von PHP transliterator_transliterate passieren, denn danach ist die Auskunft verloren: aus einem a lässt sich nicht mehr ablesen, ob dort ein a oder ein ä stand. Ein Reparaturversuch im Nachhinein würde aus jedem echten a ebenfalls ein ae machen.

Daran hängt mehr als ein Schreibfehler. Wer eine Bestandsseite mit deutschen URLs auf die Umschrift umstellt, hat in jedem Slug statt ue nur noch ein blankes u, und jede alte Adresse zeigt auf einen 404. Solche Umstellungen brauchen eine Weiterleitungstabelle, und Slugs werden einmal berechnet und gespeichert, nicht bei jedem Seitenaufruf neu.

Praxis: mit PHP transliterator_transliterate() einen Slug erzeugen

Umschrift allein ergibt noch keinen Slug. Größe & Gewicht: Müllers Läden wird zu Grosse & Gewicht: Mullers Laden, und das ist weiterhin keine URL. Es fehlen die Kleinschreibung und das Aufräumen aller Zeichen, die in einer Adresse nichts verloren haben. Mit diesen drei Schritten wird aus PHP transliterator_transliterate eine fertige Funktion.

<?php

function slug(string $text, string $fallback = 'eintrag'): string
{
/* Schritt 1a: deutsche Umlaute nach Hauskonvention */
$text = strtr($text, [
'ä' => 'ae', 'ö' => 'oe', 'ü' => 'ue',
'Ä' => 'Ae', 'Ö' => 'Oe', 'Ü' => 'Ue',
'ß' => 'ss',
]);

/* Schritt 1b: Umschrift plus Kleinschreibung.
Lower in der Kette ist multibyte-sicher,
strtolower() waere es nicht. */
$roh = transliterator_transliterate(
'Any-Latin; Latin-ASCII; Lower',
$text
);

if ($roh === false) {
return $fallback;
}

/* Schritt 2: alles ausser a-z und 0-9 wird Trennstrich.
Der Quantor + fasst Folgen zu einem Strich zusammen. */
$roh = preg_replace('/[^a-z0-9]+/', '-', $roh);

/* Schritt 3: Trennstriche an den Raendern weg */
$roh = trim($roh, '-');

/* Ohne Fallback stuende hier eine leere URL */
return $roh === '' ? $fallback : $roh;
}

echo slug('Größe & Gewicht: Müllers Läden');
/* groesse-gewicht-muellers-laeden */

echo slug('Санкт-Петербург'); /* sankt-peterburg */
echo slug('Ελληνικά Νέα'); /* ellenika-nea */
echo slug('北京大学'); /* bei-jing-da-xue */
echo slug('مرحبا بالعالم'); /* mrhba-bal-alm */
echo slug('Иванов'); /* ivanov */
echo slug('!!!'); /* eintrag */

Die letzte Zeile ist der Notausgang. Bei einer Eingabe aus lauter Satzzeichen bleibt nach dem Ersetzen nichts übrig, und eine leere Adresse ist keine Adresse. Der Filter [^a-z0-9]+ erledigt nebenbei eine zweite Aufgabe: er fängt genau die Reste ab, die Latin-ASCII stehen lässt, also das arabische ʿ und die Währungszeichen. Zur Zeichenklasse hilft das Tutorial zu regulären Ausdrücken, zum Aufruf drumherum das zu preg_replace() und zum Beschneiden am Ende das zu trim().

Eine Abgrenzung gehört hierher, weil zwei Wege dasselbe Problem lösen und sich trotzdem nicht ersetzen. Die Umschrift erzeugt eine lesbare URL, urlencode() eine korrekte, aber unlesbare. Ein kyrillischer Titel überlebt die Prozentkodierung unbeschadet und ergibt eine Adresse aus Dutzenden Prozentzeichen.

Dieselbe Funktion taugt für eine zweite Aufgabe. Wer ein Suchfeld baut, in dem "Dvorak" auch Dvořák finden soll, legt neben der Originalschreibweise eine reduzierte Spalte an und schickt gespeicherten Wert und Suchanfrage durch dieselbe Kette. Die Transliteration ersetzt die Anzeige dabei nicht, sie steht als zweite Spalte daneben und wird ausschließlich zum Vergleichen abgefragt.

Transliterator::create() und die objektorientierte Form

Wird dieselbe Regel tausendfach angewendet, etwa in einer Schleife über einen Datenimport, lohnt sich das Objekt. Transliterator::create() baut es einmal, danach ist es beliebig oft verwendbar, statt dass PHP transliterator_transliterate die Kennung bei jedem Aufruf neu auflöst. Ein fachlicher Unterschied besteht nicht, das Objekt passt sogar als erster Parameter in die prozedurale Funktion hinein.

<?php

/* Einmal bauen, danach beliebig oft verwenden */
$umschrift = Transliterator::create('Any-Latin; Latin-ASCII');

if ($umschrift === null) {
exit('Regel nicht verfuegbar: ' . intl_get_error_message());
}

echo $umschrift->id;
/* Any-Latin;Latin-ASCII (ICU entfernt die Leerzeichen) */

foreach (['Москва', 'Αθήνα', '東京'] as $stadt) {
echo $umschrift->transliterate($stadt) . "\r\n";
}
/* Moskva
Athena
dong jing */

/* Das Objekt passt auch in die prozedurale Funktion */
echo transliterator_transliterate($umschrift, 'Киев');
/* Kiev */

Zwei Kleinigkeiten fallen auf. create() gibt bei einer unbekannten Kennung null aus und nicht false, die Abfrage sieht also anders aus als bei der prozeduralen Form. Und die Eigenschaft id zeigt die normalisierte Kennung: ICU wirft die Leerzeichen um die Semikolons heraus. Wer die Kleinschreibung außerhalb einer Regel-Kette braucht, greift zu mb_strtolower(), denn strtolower() arbeitet bytweise und macht aus ÄRGER nur ein Ärger.

Eigene Regeln und die Rückrichtung

Wer die Umlautregel nicht an drei Stellen im Projekt pflegen will, gießt sie in ein eigenes Regelwerk. Transliterator::createFromRules() nimmt ICU-Syntax entgegen, jede Regel hat die Form quelle > ziel;. Damit steht die Hausregel an einer Stelle und lässt sich wie jede eingebaute Kennung an PHP transliterator_transliterate übergeben.

<?php

/* Eigenes Regelwerk in der ICU-Syntax: quelle > ziel; */
$deutsch = Transliterator::createFromRules(
'ä > ae; ö > oe; ü > ue; ß > ss;'
. ' Ä > Ae; Ö > Oe; Ü > Ue;',
Transliterator::FORWARD
);

if ($deutsch === null) {
exit('Regelwerk fehlerhaft: ' . intl_get_error_message());
}

echo $deutsch->transliterate('Größe Öl Ärger Müller');
/* Groesse Oel Aerger Mueller */

/* Rueckrichtung: REVERSE dreht eine Regel um */
$zurueck = Transliterator::create(
'Latin-Cyrillic',
Transliterator::REVERSE
);

echo $zurueck->id; /* Cyrillic-Latin */
echo $zurueck->transliterate('Привет'); /* Privet */

$hin = Transliterator::create('Latin-Cyrillic');
echo $hin->transliterate('Privet'); /* Привет */

/* Achtung: nach Latin-ASCII ist kein Zurueck mehr moeglich.
Die Diakritika sind dann ersatzlos verloren. */

Ein Regelwerk mit Syntaxfehler ergibt null, und die Begründung steht in intl_get_error_message(). Ein doppeltes Größerzeichen quittiert ICU mit parse error at offset 0 und dem Code U_UNQUOTED_SPECIAL. Die Abfrage auf null ist die einzige Stelle, an der so ein Tippfehler auffällt.

Zur Rückrichtung ein nüchterner Hinweis: sie gelingt nur bei Regeln mit echter Gegenrichtung wie Latin-Cyrillic. Nach Latin-ASCII gibt es kein Zurück, weil niemand mehr weiß, welches e einmal ein é war.

Wenn PHP transliterator_transliterate() false liefert

Zwei Betriebsfragen bleiben, und beide treffen vor allem den, der seine Anwendung an fremde Server ausliefert. Die erste ist die Verfügbarkeit: ohne die intl-Erweiterung gibt es PHP transliterator_transliterate gar nicht, und der Aufruf endet in einem Call to undefined function statt in einer Warnung. Die zweite ist die ungültige Kennung, die eine Warnung auslöst und false ausgibt, ohne das Skript abzubrechen.

<?php

/* Ohne intl gibt es die Funktion nicht.
Ein Aufruf endet dann in einem Fatal Error. */
if (!extension_loaded('intl')) {
exit('Die Erweiterung intl fehlt auf diesem Server.');
}

/* Ungueltige Kennung: Warnung plus Rueckgabe false */
$ergebnis = transliterator_transliterate('Gibt-Es-Nicht', 'Test');

var_dump($ergebnis);
/* bool(false) */

/* Bei der prozeduralen Form mit String-Kennung existiert
kein Objekt, das man fragen koennte. Deshalb intl_*: */
echo intl_get_error_message();
/* transliterator_create: unable to open ICU transliterator
with id "Gibt-Es-Nicht": U_INVALID_ID */

echo intl_get_error_code();
/* 65569 */

/* transliterator_get_error_message() braucht zwingend ein
Objekt. Ein Aufruf ohne Argument endet im ArgumentCountError. */
$objekt = Transliterator::create('Any-Latin; Latin-ASCII');

echo transliterator_get_error_message($objekt); /* U_ZERO_ERROR */
echo transliterator_get_error_code($objekt); /* 0 */

/* Immer mit === pruefen, denn eine leere Eingabe liefert
voellig regulaer einen leeren String zurueck. */
if ($ergebnis === false) {
echo 'Umschrift fehlgeschlagen';
}

Der Kommentar zu transliterator_get_error_message() korrigiert eine verbreitete Fehlannahme. Die Funktion hat keine parameterlose Variante, ihre Signatur verlangt ein Transliterator-Objekt. Bei der prozeduralen Form mit einer Zeichenkette als Kennung entsteht kein Objekt, also ist dort intl_get_error_message() zuständig. Vier weitere Beobachtungen begegnen einem rund um PHP transliterator_transliterate besonders oft.

Der Text kommt unverändert wieder heraus

Dann steht Latin-ASCII ohne Any-Latin davor. Die Regel greift nur auf lateinische Zeichen und ignoriert Kyrillisch, Griechisch und Arabisch.

Ein leeres Ergebnis wird als Fehler behandelt

Eine leere Eingabe ergibt regelkonform eine leere Zeichenkette. Nur false ist ein Fehlschlag, deshalb der Vergleich mit ===.

Die Offsets liegen daneben

Wer $start und $end mit strlen() oder mb_strlen() füllt, rechnet in Bytes oder Zeichen. Gerechnet wird aber in UTF-16-Codeeinheiten, und außerhalb der Basic Multilingual Plane gehen die Grenzen auseinander.

Auf dem alten Server sieht das Ergebnis anders aus

Die Regeln stammen aus ICU, und ICU-Versionen unterscheiden sich. Die Werte hier sind mit ICU 76.1 gemessen. Ein gespeicherter Slug bleibt davon unberührt, ein bei jedem Aufruf neu berechneter nicht.

PHP transliterator_transliterate(), Normalizer und iconv im Vergleich

Drei Werkzeuge bearbeiten Zeichenketten auf ähnliche Weise und werden regelmäßig verwechselt. Die klarste Trennlinie verläuft zwischen den beiden intl-Klassen: Normalizer vereinheitlicht dieselbe Schrift, damit sich Zeichenketten vergleichen lassen. Transliterator wechselt die Schrift, damit Menschen und Systeme lesen können, was dasteht.

Konkret heißt das: Normalizer::normalize() bekommt zwei Zeichenketten, die auf dem Bildschirm gleich aussehen, und macht daraus zwei, die auch im Speicher gleich sind. Das é als ein Zeichen und das é aus e plus Akzent bleiben beide ein é, sie liegen nur in derselben Form vor. PHP transliterator_transliterate verfolgt das Gegenteil: danach steht dort etwas, was vorher nicht dastand, dafür kann ein lateinisches Alphabet es lesen. Daraus folgt die Reihenfolge im Code. Wer beides braucht, normalisiert zuerst auf NFC und schickt das Ergebnis danach durch den Transliterator. Umgekehrt ergibt es keinen Sinn. Welche vier Formen Normalizer dabei kennt und wann welche davon gebraucht wird, füllt ein eigenes Tutorial.

Kriterium transliterator_transliterate() Normalizer iconv //TRANSLIT eigene strtr()-Liste
Zweck Schrift wechseln Schreibweise vereinheitlichen Zeichen annähern beim Kodierungswechsel Feste Zeichen ersetzen
Gleiches Ergebnis auf jedem Server ja, bei gleicher ICU-Version ja nein, hängt an Gebietsschema und C-Bibliothek ja
Erweiterung nötig intl intl iconv, meist vorhanden keine
Typischer Einsatz Slugs, Dateinamen, Suchspalten Vergleiche, Sortierung, Dubletten Altcode ohne intl reine Umlautregel

Der entscheidende Nachteil steht in der zweiten Zeile der vierten Spalte: iconv('UTF-8', 'ASCII//TRANSLIT', $text) hängt am Gebietsschema und an der C-Bibliothek des Servers. Dasselbe Skript kann unter glibc und unter musl verschiedene Ergebnisse liefern, und bei einem unbekannten Zeichen kommt mal ein Fragezeichen heraus, mal nichts. PHP transliterator_transliterate verhält sich dagegen auf jeder Maschine gleich, weil ICU die Regeln mitbringt. Der Preis ist die Abhängigkeit von intl. Eine eigene Austauschliste bleibt sinnvoll, aber nur für einen abgesteckten Zeichenvorrat wie die deutschen Umlaute.

Die deutschen Umlaute gehören vor die Regelkette, die Fehlerprüfung dahinter und der Slug-Filter ganz ans Ende.

flowchart TD
    A[Fremde Schrift im Text] --> B{intl da?}
    B -->|Nein| C[extension_loaded testen]
    B -->|Ja| D{Deutsche Umlaute?}
    D -->|Ja| E[Erst strtr ae oe ue ss]
    D -->|Nein| F[Regelkette setzen]
    E --> F
    F --> G[Any-Latin dann Latin-ASCII]
    G --> H{Ergebnis false?}
    H -->|Ja| I[intl_get_error_message]
    H -->|Nein| J{Slug gebraucht?}
    J -->|Ja| K[Lower dann preg_replace]
    J -->|Nein| L[Text direkt nutzen]

Fazit

PHP transliterator_transliterate wechselt die Schrift und nicht die Sprache. Das Arbeitspferd ist die Kette Any-Latin; Latin-ASCII: das erste Glied bringt den Text ins lateinische Alphabet, das zweite räumt die dabei entstandenen Diakritika ab. Ist die Ausgangssprache bekannt, liefert eine Regel wie Russian-Latin/BGN deutlich lesbarere Ergebnisse.

Der wichtigste Satz für deutschsprachige Projekte lautet trotzdem anders: Latin-ASCII macht aus ä ein a. Wer ae braucht, ersetzt die Umlaute vor dem Aufruf selbst. Ein vollständiger Slug entsteht aus Umschrift, Kleinschreibung, preg_replace() und einem Rückfallwert für den leeren Fall. Vor dem ersten Einsatz gehört ein extension_loaded('intl') in den Code, das Ergebnis wird mit === gegen false geprüft, und die Begründung holt intl_get_error_message(). Damit ist PHP transliterator_transliterate das verlässlichste Werkzeug, das PHP für Umschrift zu bieten hat.

 

Tags:

 

 

Kommentare (0)

Noch keine Kommentare. Sei der Erste!

Melde dich an, um einen Kommentar zu schreiben.
Bücherregal mit drei Büchern: 'PHP 4 - Grundlagen und Profiwissen' von Hanser Verlag, 'Webdesign in a Nutshell' von O'Reilly Verlag, und 'Webgestaltung' von Galileo Computing.