Dieter Raber: Sprachverwaltungs-System für WebApp

Beitrag lesen

Hallo Lupus,

der Klassiker fuer Uebersetungen ist eigentlich gettext. PHP hat dafuer die schoene Faulenzerfunktion _(). In diesem Zusammenhang ist poedit sowas wie ein Standardeditor fuer die Uebersetzungsdateien. Im Prizip funktioniert das so, dass du eine Uebersetzungsdatei hast mit jeweils Wertepaaren in, sagen wir, Englisch und Deutsch. Du rufst die Function auf mit _('Some string') und das ergibt in deiner Applikation 'Irgendeine Zeichenkette', falls die Uberseztung vorhanden ist oder eben 'Some string', falls nicht.

Gettext ist erst einmal etwas gewoehnungsbeduerftig, zum anderen nicht auf allen Servern vorhanden.

Alternativ kann man das auch so machen, dass man alle Uebersetzungen in eine Ini-Datei schreibt und von dort ausliest. Wir machen das in der Firma etwas aufwaendiger mit einer Datenbank, und das klappt recht gut.

Unsere Tabelle sieht so aus:

iniKey | en     | de        | fr        | ...  
-----------------------------------------------------  
cancel | Cancel | Abbrechen | Annuller  | ...

Diese Tabelle laesst sich mit phpMyAdmin gut warten und man vermeidet Probleme mit fehlerhaften/fehlenden Keys etc.

Daraus generieren wir regelmaessig fuer alle Sprachen je eine Datei 'locale.ini.php', die so aussieht:

;<? die() ?> -> vermeidet diekten Aufruf via HTTP
;ö           -> macht dem Editor klar, dass es sich um UTF-8 handelt
[vocabulary]
cancel = "Annuller"

Diese Datei wird beim Applicationstart mit parse_ini_file() eingelesen. In den Userkommentaren zu dieser Funktion findest du auch einige brauchbare Funktionen um ini-Files zu schreiben, das musst du natuerlich wissen, wenn du die Daten aus einer DB einlesen willst.

Egal, ob du den Umweg ueber eine DB nimmst oder nicht, hast du jetzt ein Array (sagen wir $vocabulary) mit allen Uebersetzungen einer Sprache. Bei uns sind das so ca. 200, das geht problemlos.

Jetzt zu den etwas komplizierteren Faellen - Du wirst Uebersetzungen in der Art 'Found 35 results' vs. '35 Ergebnisse gefunden' haben, wo du also eine Variable '35' mit in die Uebersetzung einbauen willst, deren Position von der Sprache abhaengig ist. Deine Uebersetzung koennte jetzt so aussehen:
found_num_results = "Found %d results"

Fuer solche Faelle muesste Deine Funktion sprintf() koennen.

Eine Beispielfunktion waere etwa so, man nennt die haeufig __() (2 underscores)

function __($key) {  
  global $vocabulary;//nee, mit gefaellt das global auch nicht, aber ich will es hier einfach halten  
  if(!isset($vocabulary[$key])) {  
    return $key; // key nicht vorhanden, return $key  
  }  
  $args = func_get_args();  
  return call_user_func_array('sprintf', $args);  
}

Diese kannst du mit __('cancel'), oder aber __('found_num_results', 35) aufrufen (oder eben noch mehr Argumenten, sie nochmal sprintf();

Jetzt gibt es noch ein paar Dinge, auf die ich dich aufmerksam machen moechte. Anstatt von 'lang' solltest du vielleicht lieber von 'locale' sprechen, Wikipedia kann das nett erklaeren. Wenn du in deiner Uebersetung Apostroph meinst, solltest du auch Apostroph sagen und nicht '. Das Zeichen kriegst du mit ALT + 0146. Allerdings musst du deine Anwendung dann ganz in UTF-8 halten, aber das ist sowieso eine gute Idee.

Dein Locale-Detector ist an sich gut gedacht, aber was ist mit _GET und _SESSION? Und das @ vor _COOKIE ist hoffentlich nur ein Vertipper, ansonsten waere es a.) unnoetig und b.) schlechter Stil.

Du koenntest das auch etqa so machen:

if(!empty($_GET['locale'])) {  
  $locale = $_GET['locale'];  
}  
else if ... POST COOKIE SESSION...  
  
if(is_file('pfad/zu/inis/'. $locale . '/locale.ini.php')) {  
  $locale_file = 'pfad/zu/inis/'. $locale . '/locale.ini.php';  
}  
else {  
  $locale_file = 'pfad/zu/inis/en/locale.ini.php';// default Sprachdatei  
}  
$vocabulary = parse_ini_file($locale_file)

Das war jetzt etwas langatmig, aber ich hoffe, es hilft Dir weiter

Dieter