Programmieren von mehrsprachigen PHP-Anwendungen

Lesezeit: 7 Minuten

Programmieren von mehrsprachigen PHP Anwendungen
morristhebear

Ich entwickle eine PHP-Anwendung und überlege, wie ich am besten mehrsprachige Unterstützung für Benutzer in anderen Ländern einbeziehen kann.

Ich beherrsche PHP, habe aber noch nie etwas mit Unterstützung für andere Sprachen entwickelt.

Ich dachte daran, die Sprache in eine PHP-Datei mit Konstanten zu schreiben, Beispiel:

en.php könnte enthalten:

define('HZ_DB_CONN_ERR', 'There was an error connecting to the database.');

und fr.php könnte enthalten:

define('HZ_DB_CONN_ERR', 'whatever the french is for the above...');

Ich könnte dann eine Funktion aufrufen und automatisch die richtige Sprache übergeben lassen.

hz_die('HZ_DB_CONN_ERR', $this);

Ist das ein guter Weg?

— morristhebear.

Seltsam. Die Leute scheinen die offensichtliche Lösung zu ignorieren. Ihre Vorstellung von gebietsschemaspezifischen Dateien ist in Ordnung. Habe en.php:

define('LOGIN_INCORRECT','Your login details are incorrect.');
...

Angenommen, Sie haben eine globale Konfigurations-/Konstantendatei (was ich aus vielen Gründen vorschlagen würde), haben Sie Code wie diesen:

if ($language == 'en') {
  reqire_once 'en.php';
} else if ($language == 'de') {
  require_once 'de.php';
}

Sie können Funktionen für Zahlen- und Währungsanzeige, Vergleich/Sortierung (dh Deutsch, Französisch und Englisch haben alle unterschiedliche Sortiermethoden) usw. definieren.

Die Leute vergessen oft, dass PHP eine dynamische Sprache ist, also Dinge wie diese:

if ($language == 'en') {
  function cmp($a, $b) { ... }
} else if ($language == 'de') {
  function cmp($a, $b) { ... }
}

sind eigentlich vollkommen legal. Benutze sie.

  • Guter Gedanke, ich stimme diesem Ansatz zu

    – Codex73

    2. Oktober ’09 um 16:49

  • Ich würde solche Konstanten nur verwenden, wenn die Sprachdateien aus einer Datenbank generiert und aus benutzergenerierten Inhalten abgeleitet wurden. Andernfalls kann es unhaltbar werden, wenn neue Strings usw. hinzugefügt werden. Es neigt auch dazu, sich mit verlassenen zu füllen.

    – DanMan

    20. Dezember ’12 um 14:34

1641813116 706 Programmieren von mehrsprachigen PHP Anwendungen
OIS

Sie können verwenden Gettext oder etwas, das gettext sowie mehr unterstützt, wie zum Beispiel Zend_Translate.

Bearbeiten:

Nur der Genauigkeit halber unterstützt Zend_Translate gettext ohne das gettext Modul. Sie können hier sehen die vielen verschiedenen Eingabearten, die es unterstützt.

Wenn du Arrays wie auch vorgeschlagen verwendest, kannst du dies auch mit Zend_Translate verwenden. Der Punkt ist, wenn Sie heute Arrays verwenden und morgen gettext, xml oder etwas anderes verwenden, müssen Sie nur Ihre Konfiguration für Zend_Translate ändern.

Mir gefällt folgender Ansatz sehr gut:

eine Datei ist der Übersetzer selbst:

class Translator{
    private static $strs = array();
    private static $currlang = 'en';

    public static function loadTranslation($lang, $strs){
        if (empty(self::$strs[$lang]))
            self::$strs[$lang] = array();

        self::$strs[$lang] = array_merge(self::$strs[$lang], $strs);        
    }

    public static function setDefaultLang($lang){
        self::$currlang = $lang;        
    }

    public static function translate($key, $lang=""){
        if ($lang == "") $lang = self::$currlang;
        $str = self::$strs[$lang][$key];
        if (empty($str)){
            $str = "$lang.$key";            
        } 
        return $str;       
    }    

    public static function freeUnused(){
        foreach(self::$strs as $lang => $data){
            if ($lang != self::$currlang){
                $lstr = self::$strs[$lang]['langname'];
                self::$strs[$lang] = array();
                self::$strs[$lang]['langname'] = $lstr;                
            }            
        }        
    }

    public static function getLangList(){
        $list = array();
        foreach(self::$strs as $lang => $data){
            $h['name'] = $lang;
            $h['desc'] = self::$strs[$lang]['langname'];
            $h['current'] = $lang == self::$currlang;
            $list[] = $h;
        }
        return $list;        
    }

    public static function &getAllStrings($lang){
        return self::$strs[$lang];
    }

}

function generateTemplateStrings($arr){
    $trans = array();
    foreach($arr as $totrans){
        $trans[$totrans] = Translator::translate($totrans);
    }
    return $trans;    
}

die Sprachdateien können einfach sein include()d und sehen so aus:

de.php:

Translator::loadTranslation('en', array(
  'textfield_1'          => 'This is some Textfield',
  'another_textfield '   => 'This is a longer Text showing how this is used',
));

de.php:

Translator::loadTranslation('de', array(
  'textfield_1'          => 'Dies ist ein Textfeld',
  'another_textfield '   => 'Dies ist ein längerer Text, welcher aufzeigt, wie das hier funktioniert.',
));

In Ihrer App können Sie entweder eine Zeichenfolge wie folgt übersetzen:

$string = Translator::translate('textfield_1')

oder sogar ein paar Saiten:

$strings = generateTemplateStrings(array('textfield_1', 'another_textfield'));

Da die Sprachdateien einfach eingefügt werden können, können Sie die sehr einfach stapeln und beispielsweise zuerst eine globale Datei einbinden und dann Dateien aus Submodulen einschließen, die entweder neue Strings hinzufügen oder bereits definierte ersetzen können (was mit dem nicht funktioniert) define()-Methode).

Da es sich um reines PHP handelt, kann es sogar sehr einfach im Opcode-Cache gespeichert werden.

Ich habe sogar Skripte, die CSV-Dateien mit unübersetzten Strings aus einer Datei generieren und noch besser: die übersetzte CSV-Datei zurück in die Sprachdatei konvertieren.

Ich habe diese Lösung seit 2004 produktiv im Einsatz und bin damit sehr zufrieden.

Natürlich können Sie es sogar um Konventionen zum Pluralisieren erweitern. Zahlenformate zu lokalisieren ist jedoch etwas, was Sie mit anderen Mitteln tun müssten – die intl-Erweiterung fällt mir ein.

  • Ich versuche, Ihren obigen Weg zu implementieren, aber ich kann nicht herausfinden, wie und wo die zweite Sprache definiert werden soll. Die “translator.php” scheint die andere Sprache (zB “de”) nicht zu enthalten und auch dieses Skript scheint die Sprachänderung meiner Website nicht automatisch zu erkennen. Ich bekomme nur die “en”-Übersetzungen. Für Tipps wäre ich hier sehr dankbar.

    – otinai

    15. Apr. ’13 um 22:58

Danke an alle Menschen für eure Ansätze und Lösungen. Ich bin mit den gleichen anfänglichen Zweifeln hierher gekommen und kann schlussfolgern, dass die Verwendung der “Define-Methode” realistischer ist, da sie selbst bei dem seltsamen Problem, dass bei anderen Bibliotheken oder anderen keine sehr stilvollen Methoden verwendet werden, realistisch ist und in einem produktiven Denken, ist so einfach zu verwalten und zu verstehen, so dass Sie andere Sprachen durch Nicht-Programmierfähigkeiten lernen können.

Ich halte die Arrays-Methode für besser, da Sie nicht so viele Sprachen verteilen müssen, um Traductions zu erhalten, außerdem verbrauchen Sie weniger Speicher, da Sie nur die benötigten Traducted-Strings laden.

Darüber hinaus können diese nicht neu definiert werden; Nun, im Allgemeinen, wenn Sie Konstanten definieren, liegt das daran, dass sie nicht geändert werden müssen oder dürfen. Bei Bedarf können Sie also einen Abschnitt für definierte Strings und variable verwenden.

Ich füge hinzu, dass mir die Art und Weise, wie diese Definitionsdateien aussehen, nicht gefällt, aber bedenken Sie, dass Ihre Besucher sich überhaupt keine Sorgen über die Art und Weise machen, wie das Idiom implementiert wird, es ist eine perfekte gültige Implementierung und Sie können leicht einige Traductions erhalten.

Vielleicht möchten Sie sich ein Framework wie CakePHP oder CodeIgniter ansehen, das das Schreiben internationalisierter Anwendungen erheblich erleichtert. Es sind nicht nur Zeichenfolgen, die Sie berücksichtigen müssen – auch Dinge wie Zahlenformate und Datumsformate müssen berücksichtigt werden

  • Ich bin im Allgemeinen kein Fan von vollständigen MVC-Frameworks (ich verwende Smarty jedoch gerne), ich bin noch in der Anfangsphase der Entwicklung und hatte noch nicht über Währungen und Datumsformate nachgedacht, werde dies jedoch berücksichtigen. .. Danke!

    – morristhebear

    16. Januar ’09 um 15:56 Uhr

  • IMHO CakePHP ist komplett übertrieben (und aufgebläht wie 99% der MVC-Frameworks).

    – kletus

    17. Januar ’09 um 6:13

Ihre Lösung sollte gut funktionieren, solange sie ausschließlich zum Übersetzen gedacht ist. Wie andere bereits erwähnt haben, gibt es viele andere gebietsschemabasierte Variablen, z. B. Währungs- und Datumsformate.

Ein solider Ansatz, um Ihr Anwendungsgebietsschema sicher zu machen, wäre die Verwendung von Zend_Locale kombiniert mit Zend_Translate.

Zend_Locale ermöglicht es Ihnen, das Gebietsschema des Benutzers leicht zu erkennen oder es einzustellen, wenn Sie es wünschen. Diese Klasse ist nützlich für die automatische Einstellung der richtigen Währungsformat, zum Beispiel.

Zend_Translate ermöglicht Ihnen das einfache Übersetzen von Text mit mehreren verschiedenen Formate:

  • Array
  • CSV
  • Gettext
  • Ini
  • Tbx
  • Tmx
  • Qt
  • Xliff
  • XmlTm

  • Ich bin im Allgemeinen kein Fan von vollständigen MVC-Frameworks (ich verwende Smarty jedoch gerne), ich bin noch in der Anfangsphase der Entwicklung und hatte noch nicht über Währungen und Datumsformate nachgedacht, werde dies jedoch berücksichtigen. .. Danke!

    – morristhebear

    16. Januar ’09 um 15:56 Uhr

  • IMHO CakePHP ist komplett übertrieben (und aufgebläht wie 99% der MVC-Frameworks).

    – kletus

    17. Januar ’09 um 6:13

Programmieren von mehrsprachigen PHP Anwendungen
jishi

Ihr Ansatz ist praktikabel, wenn Sie verschiedene Konstantendateien hinzufügen, je nachdem, welche Sprache der Benutzer ausgewählt hat.

Sie könnten auch den konstanten Teil überspringen und einfach eine große Hashtabelle mit konstant => Übersetzung definieren, um Abstürze im Namensraum zu vermeiden.

Datei: de.php

$constants = Array(
 'CONSTANT_KEY' => 'Translated string'
);

Datei: Funktionen.php

function getConstant($key, $fallback) {
   // ... return constant or fallback here.
}

Bei großen Datenmengen wird dieser Ansatz jedoch schwer zu pflegen sein. Es gibt ein paar andere Ansätze, die Ihren Zweck besser erfüllen könnten, zum Beispiel ist eine ideale Lösung, wenn alle Ihre Konstanten in einem globalen Speicherbereich für Ihre gesamte Site gespeichert werden, um zu vermeiden, dass jede einzelne Anfrage/jeder Thread all diese übersetzten Daten speichert Erinnerung. Dies erfordert eine Art PHP-Modul-Ansatz. Gettext, wie jemand hier vorgeschlagen hat, könnte diesen Ansatz verwenden.

Google für PHP-Lokalisierung, um nützliche Ressourcen zu finden.

.

296930cookie-checkProgrammieren von mehrsprachigen PHP-Anwendungen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy