it-swarm.com.de

Die effizienteste Möglichkeit, Sprachdateien in PHP zu erstellen?

Fragen aktualisiert, anstatt eine neue Frage zu stellen ...

Ich möchte wirklich ein paar andere alternative Sprachen als Englisch auf meiner Website für soziale Netzwerke anbieten. Dies ist das erste Mal, dass ich irgendeine Art von Sprachübersetzung mache. Bitte nehmen Sie sie mit.
Ich recherchiere, bin also offen und offen für Ideen und habe schon eine Menge Fragen.

1)
Was heißt das, ich sehe es oft, wenn ich nach Sprachübersetzungen auf SO recherchiere?

2)
Die meisten Leute sagen, dass use gettext PHP eine Erweiterung oder Unterstützung dafür hat,
Nun, ich habe es recherchiert und ich habe ein grundlegendes Verständnis davon, soweit ich sagen kann, ist es eine Menge zusätzlicher Arbeit, diesen Weg zu gehen.
Ich meine, meine Website so zu codieren, dass sie ihre Funktionen verwendet, z. _ ('Hallo Welt, ich bin jetzt auf Englisch') oder gettext ('Hallo Welt, ich bin jetzt auf Englisch') ist kein Problem für jede Route, die ich gehe wird das erfordern.
Aber dann musst du gettext auf deinem Server installieren und es zum Laufen bringen,
Verwenden Sie dann einige spezielle Editoren, um spezielle Dateien zu erstellen und sie zu kompilieren, denke ich?

Klingt nach Schmerz, ich verstehe, dass dies der beste Weg sein soll, nun, jeder scheint es zu sagen.
Kann mir jemand sagen, warum dies der richtige Weg ist?

3)
Ich mag die Einfachheit dieses Ansatzes sehr. Wenn Sie nur ein Spracharray erstellen und die Phrase aufrufen, die Sie in einer Funktion wie dem folgenden Beispiel benötigen, fügen Sie einfach eine Datei mit dem entsprechenden Spracharray hinzu.

Was ich wirklich wissen möchte, ist, ob dies die weniger leistungsfähige Methode auf einer stark frequentierten und ziemlich großen Site ist als bei der Verwendung von gettext. Wenn ja, können Sie bitte erklären, warum?

<?PHP
//Have seperate language files for each language I add, this would be english file
function lang($phrase){
    static $lang = array(
        'NO_PHOTO' => 'No photo\'s available',
        'NEW_MEMBER' => 'This user is new'
    );
    return $lang[$phrase];
}
//Then in application where there is text from the site and not from users I would do something like this
echo lang('NO_PHOTO');  // No photo's available would show here
?>

* Code aus der Antwort von brianreavis unten

24
JasonDavis

Das Rad nicht neu erfinden. Verwenden Sie zum Beispiel gettext oder Zend_Translate .

4
raspi

Es ist wahrscheinlich am besten, eine Funktion zu definieren, die Ihre Sprachzuordnung behandelt. Wenn Sie do später ändern möchten, müssen Sie nicht hunderte Skripts nach Fällen durchsuchen, in denen Sie $lang[...] verwendet haben, und sie durch etwas anderes ersetzen.

So etwas würde funktionieren und wäre nett und schnell:

function lang($phrase){
    static $lang = array(
        'NO_PHOTO' => 'No photo\'s available',
        'NEW_MEMBER' => 'This user is new'
    );
    return $lang[$phrase];
}

Machen Sie sicher das Array wird innerhalb der Funktion als static deklariert, damit es nicht bei jedem Aufruf der Funktion neu zugewiesen wird. Dies ist besonders wichtig, wenn $lang wirklich groß ist.

Um es zu benutzen:

echo lang('NO_PHOTO');

Wenn Sie mehrere Sprachen verwenden möchten, müssen Sie diese Funktion nur in mehreren Dateien definieren (z. B. en.php, fr.php usw.) und require() die für den Benutzer geeignete. 

21
brianreavis

Das könnte besser funktionieren:

function _L($phrase){
static $_L = array(
    'NO_PHOTO' => 'No photo\'s available',
    'NEW_MEMBER' => 'This user is new'
);

     return (!array_key_exists($phrase,$_L)) ? $phrase : $_L[$phrase];
}

Das ist was ich jetzt benutze. Wird die Sprache nicht gefunden, wird anstelle eines Fehlers die Phrase zurückgegeben.

Sie sollten beachten, dass ein Array nicht mehr als ~ 65500 Elemente enthalten kann. Sollte aber gut genug sein, nur zu sagen.

Hier ist ein Code, mit dem ich die Sprache des Benutzers überprüfe:

<?php
function setSessionLanguageToDefault() {
    $ip=$_SERVER['REMOTE_ADDR'];
    $url='http://api.hostip.info/get_html.php?ip='.$ip;
    $data=file_get_contents($url);
    $s=explode (':',$data);
    $s2=explode('(',$s[1]);

    $country=str_replace(')','',substr($s2[1], 0, 3));

    if ($country=='us') {
        $country='en';
    }

    $country=strtolower(ereg_replace("[^A-Za-z0-9]", "", $country ));
    $_SESSION["_LANGUAGE"]=$country;
}

if (!isset($_SESSION["_LANGUAGE"])) {
    setSessionLanguageToDefault();
}

if (file_exists(APP_DIR.'/language/'.$_SESSION["_LANGUAGE"].'.php')) {
    include(APP_DIR.'/language/'.$_SESSION["_LANGUAGE"].'.php');
} else {
    include(APP_DIR.'/language/'.DEFAULT_LANG.'.php');
}

?>

Es ist noch nicht fertig, aber ich denke, das kann viel helfen.

10
Rob Quist

Schreiben Sie nicht Ihren eigenen Sprachrahmen. Verwenden Sie gettext . PHP hat standardmäßige Bindings die Sie installieren können.

5
Fragsworth

Leider funktioniert gettext nicht gut und hat Probleme in verschiedenen Situationen wie auf verschiedenen Betriebssystemen (Windows oder Linux) und macht es sehr schwer zu funktionieren.

Außerdem müssen Sie viele Umgebungsvariablen und Domänen festlegen, und dies hat keinen Sinn.

Wenn ein Entwickler einfach nur die Übersetzung eines Textes erhalten möchte, sollte er nur den .mo-Dateipfad festlegen und die Übersetzung mit einer Funktion wie translate ("Hallo", "en_EN") abrufen. Mit gettext ist das nicht möglich.

1

Da die anderen Antworten nicht wirklich alle Fragen beantworten, werde ich dies in meiner Antwort berücksichtigen und eine vernünftige Alternative anbieten.

1) I18n ist die Abkürzung für Internationalisierung und hat einige Ähnlichkeiten mit I-18-n.

2) Meiner ehrlichen Meinung nach ist gettext Zeitverschwendung. 

3) Ihr Ansatz sieht gut aus. Nach was Sie suchen sollten, sind Sprachvariablen. Das WoltLab Community Framework 2.0 implementiert ein bidirektionales Sprachensystem. Es gibt einmal Sprachvariablen, die in der Datenbank gespeichert werden, und in einer Vorlage wird nur der Name der Variablen verwendet, der dann durch den Inhalt der Variablen in der aktuellen Sprache (falls verfügbar) ersetzt wird. Der zweite Teil des Systems bietet die Möglichkeit, vom Benutzer generierte Inhalte in mehreren Sprachen zu speichern (Eingabe in mehreren Sprachen erforderlich).

Grundsätzlich haben Sie den vom Entwickler definierten Schnittstellentext und den vom Benutzer definierten Inhalt. Der mehrsprachige Text des Inhalts wird in Sprachvariablen gespeichert, und der Name der Sprachvariablen wird dann als Wert für das Textfeld in der spezifischen Inhaltstabelle verwendet (als einsprachiger Inhalt ist auch möglich).

Die Struktur der WCF ist leider so, dass die Wiederverwendung von Code außerhalb des Frameworks sehr schwierig ist, aber Sie können es als Inspiration verwenden. Der Umfang des Systems hängt nur davon ab, was Sie mit Ihrer Site erreichen möchten. Wenn es groß wird, sollten Sie sich unbedingt das WCF-System ansehen. Wenn es klein ist, werden einige dedizierte Sprachdateien (de.php, en.php usw.) verwendet, von denen die richtige für die aktuelle Sprache enthalten ist.

1
Jim Martens

warum machst du es nicht einfach als mehrdimensionales Array?

<?php

$lang = array(
    'EN'=> array(
        'NO_PHOTO'=>'No photo\'s avaiable',
        'NEW_MEMBER'=>'This user is new',
    ),
    'MY'=> array(
        'NO_PHOTO'=>'Tiada gambar',
        'NEW_MEMBER'=>'Ini adalah pengguna baru',
    )
);

?>
0
user149513

Du kannst das:

class T {
const language = "English";
const home = "Home";
const blog = "Blog";
const forum = "Forum";
const contact = "Support";
}

Sie hätten für jede Sprache eine solche Datei. So verwenden Sie den Text:

There is no place like <?=T::home?>.

Der Nachteil ist, wenn Sie eine neue Konstante hinzufügen, müssen Sie dies für jede Sprachdatei tun. Wenn Sie eine vergessen haben, wird Ihre Seite für diese Sprache unterbrochen. Das ist ein bisschen unangenehm, aber es ist effizient, da es nicht erforderlich ist, ein großes assoziatives Array zu erstellen, und möglicherweise werden die Werte sogar eingebettet.

Vielleicht könnte der Zugang verbessert werden, zB:

class T {
    const home = "home";

    public static function _ ($name) {
        $value = @constant("self::$name");
        return $value ? $value : $name;
    }

    // Or maybe through an instance:
    public function __get ($name) {
        $value = @constant("self::$name");
        return $value ? $value : $name;
    }
}
echo "There is no " . T::_("place") . " like " . T::_("home");
$T = new T();
echo "There is no " . $T->place . " like " . $T->home;

Wir vermeiden immer noch das Array und verlassen uns auf constant , um die Suche durchzuführen, was meiner Meinung nach teurer ist als die direkte Verwendung der Konstanten. Der Nachteil ist, dass die Suche einen Fallback verwenden kann, wenn der Schlüssel nicht gefunden wird.

0
NateS