2009-09-12 18 views
23

Fragen aktualisiert, anstatt eine neue Frage zu machen ...Der effizienteste Weg, Sprachdateien in PHP zu erstellen?

ich mein erstes Mal tun, jede Art von Mir baue, das wird wirklich ein paar alternativen Sprachen anderes dann Englisch auf meiner sozialen Netzwerk-Site zur Verfügung stellen mag Sprachübersetzung also bitte mit mir.
Ich forsche also bin ich al ear und offen für Ideen und ich habe schon viel hier ist, sind die Fragen.

1)
Was bedeutet i18n, ich sehe es oft, wenn sie auf SO Sprachübersetzung forschen?

2)
Die meisten Leute sagen Verwendung gettext PHP eine Erweiterung oder die Unterstützung für sie hat,
gut ich es der Erforschung wurden, und ich habe ein grundlegendes Verständnis davon, soweit ich es sagen kann, ist ein viel zusätzliche Arbeit, um diese Route zu gehen,
Ich meine Codierung meiner Website, um seine Funktionen zu verwenden, dh; _ ('Hallo Welt, ich bin in Englisch für jetzt') oder sonst gettext ('Hallo Welt, ich bin in Englisch für jetzt') ist kein Problem, da jede Route, die ich gehe, wird das erfordern.
Aber dann müssen Sie Gettext auf Ihrem Server installieren und es funktioniert,
dann einige spezielle Editoren verwenden, um spezielle Dateien zu erstellen und sie kompilieren, denke ich?

Klingt wie ein Schmerz, ich verstehe, dass dies der beste Weg sein sollte, um zu gehen, aber jeder scheint zu sagen, dass es ist.
Also kann mir jemand sagen, warum das der Weg ist?

3)
Ich mag die Einfachheit dieses Ansatzes wirklich, nur eine Sprache Array Aufbau und den Aufruf der Phrase, die Sie wie im folgenden Beispiel in einer Funktion benötigen, würden Sie dann einfach ein File mit der entsprechenden Sprache Array.

Was ich wirklich wissen möchte ist, wäre dies die weniger leistungsfähigere Methode auf einer stark frequentierten und ziemlich großen Website im Vergleich zur Verwendung von gettext und wenn ja, kannst du erklären, warum bitte?

<?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 
?> 

* einige Code aus brianreavis Antwort verwendet unter

+0

Sie wissen, dass Sie _ in einem Array nicht verwenden müssen, aber ja, Sie sollten wahrscheinlich die PHP-Erweiterungen verwenden, anstatt Ihre eigene zu rollen. – SeanJA

Antwort

6

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

+8

Aber das Rad ist quadratisch! – srcspider

+12

-1. Warum? Da "Nicht das Rad neu erfinden" übermäßig missbraucht wird, bedeutet für mich, dass, anstatt etwas, das bereits ideal ist, etwas zu wiederholen, benutze es! Nicht, hey, irgendein Typ hat eine Bibliothek gemacht, die Arsch reißt, es interessiert uns nicht wirklich, dass du es nicht magst (zu kompliziert) oder was auch immer. – John

+0

Der Link Zend_Translate ist veraltet, für das v1-Framework verwenden Sie [diesen Link] (http://framework.zend.com/manual/1.12/de/zend.translate.html) & für das v2-Framework verwenden Sie [diesen] (http://framework.zend.com/manual/current/en/modules/zend.i18n.translating.html). –

5

Sie nicht Ihre eigene Sprache Rahmen schreiben. Verwenden Sie gettext. PHP hat den Standard bindings, den Sie installieren können.

+0

Ich habe heute nur einen Blick auf die Gettext-Seite von Earlier geworfen, bevor ich das gepostet habe. Ich kann nicht wirklich verstehen, wie es funktioniert. Kannst du etwas darüber erklären? – JasonDavis

+0

jasondavis: es macht genau das, was Sie versuchen, und mehr. Wenn Sie es installieren, wählen Sie irgendwo Ihre Sprachübersetzungsdatei (".po"). Sie können alle Ihre Strings in diese Datei übersetzen. Dann wickeln Sie in Ihrer Quelle alle Ihre mehrsprachigen Strings mit gettext() (oder normalerweise einem Alias, _()) und es wird Ihre aktuelle Übersetzung dieser Zeichenfolge für Sie ziehen. Es bietet auch mehrere Phrasen und einige andere wichtige Funktionen, die Sie finden werden notwendig. – Fragsworth

+1

@future Leser, ich werde sagen, wenn Ihre Website oder App nicht Hunderte zu Tausenden von Wörtern verwendet, ist die assoziative Array Weg besser als gettext. Gettext ist in seinen Implementierungen extrem veraltet und kann ein Albtraum zum Debuggen sein. Ich habe gerade drei Tage damit verbracht, es auf meinem Server zum Laufen zu bringen. Es hat viele Probleme und ist nicht gut gepflegt. Vertrau mir, du wirst auf einige seiner Probleme stoßen. Besser mit dem php-gettext (gettext emulator), einigen anderen Implementierungen oder dem Schreiben einer eigenen Bibliothek. –

-1

warum nicht Sie machen es nur als Multi-dimesional Array ... wie diese

<?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', 
    ) 
); 

?> 
+11

Dies würde mehr Speicher als nötig benötigen --- weil das * jede * Sprache für * jede * Anfrage laden würde. Es wäre besser, es in mehrere Dateien zu zerlegen und das einzige passende zu laden. – brianreavis

18

es wahrscheinlich am besten sein würde, eine Funktion zu definieren, die Ihre Sprache Mapping behandelt. Auf diese Weise werden Sie nicht gezwungen, Hunderte von Skripten für Fälle zu durchsuchen, in denen Sie $lang[...] verwendet haben und sie durch etwas anderes ersetzen, wenn Sie tun möchten, zu ändern, wie es später funktioniert.

So etwas wie dies funktionieren würde, und wäre schön & schnell:

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

Stellen sicher das Array static innerhalb der Funktion deklariert wird, so dass es nicht jedes Mal die Funktion aufgerufen wird neu zugewiesen bekommt. Dies ist besonders wichtig, wenn $lang wirklich groß ist.

es zu benutzen:

echo lang('NO_PHOTO'); 

Für mehrere Sprachen Handhabung haben nur diese Funktion in mehrere Dateien definiert (wie en.php, fr.php, usw.) und require() die passende für den Benutzer.

+2

FYI, diese Lösung ist Fragsworths Vorschlag unterlegen: 'gettext'. Gettext ist definitiv der bessere Weg für solche Dinge. Aber so würden Sie es machen, wenn Sie Ihr eigenes Basissystem rollen würden. – brianreavis

+0

beautifulloeee, ty! – themis

+0

Hallo, ich mag die Lösung! Ich komme aus C# und habe Zweifel, wie statische Variablen in PHP funktionieren.Wenn Sie eine statische Variable in C# deklarieren, z. B. ein Array, wird diese im Speicher gehalten und Sie müssen sie nur einmal laden. Der Wert bleibt zwischen verschiedenen Benutzer-Threads bestehen. Aber in PHP verliert es den Wert in jeder Ausführung, soweit ich weiß, und wenn Sie Dinge im Speicher behalten möchten, müssen Sie Alternativen wie APC verwenden. Warum @brianreavis empfehlen Sie, es statisch zu machen, um nicht jedes Mal neu zu verteilen? Vielen Dank! –

10

Dies 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]; 
} 

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

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

Hier einige Code, den ich für die Sprache des Benutzers überprüfen:

<?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'); 
} 

?> 

Sein noch nicht getan, aber auch ich denke, das viel helfen könnte.

1

Da die anderen Antworten nicht alle Fragen beantworten, werde ich in meiner Antwort darauf eingehen und eine sinnvolle Alternative anbieten.

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

2) In meiner ehrlichen Meinung ist gettext Zeitverschwendung.

3) Ihr Ansatz sieht gut aus. Was Sie suchen sollten, sind Sprachvariablen. Die WoltLab Community Framework 2.0 implementiert ein Zwei-Wege-Sprachsystem. Für einmal gibt es Sprachvariablen, die in der Datenbank gespeichert werden und innerhalb 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 eine Möglichkeit, benutzergenerierten Inhalt in mehreren Sprachen zu speichern (Eingabe in mehreren Sprachen erforderlich).

Grundsätzlich haben Sie den Schnittstellentext, der vom Entwickler definiert wird und den Inhalt, der vom Benutzer definiert wird. 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 (da auch einsprachige Inhalte möglich sind).

Die Struktur der WCF ist leider in einer Weise, dass die Wiederverwendung von Code außerhalb des Rahmens sehr schwierig ist, aber Sie können es als Inspiration verwenden. Der Umfang des Systems hängt ausschließlich davon ab, was Sie mit Ihrer Site erreichen möchten. Wenn es groß wird, sollten Sie sich unbedingt das WCF-System ansehen. Wenn es ein paar kleine dedizierte Sprachdateien sind (de.php, en.PHP, etc), von denen die richtige für die aktuelle Sprache enthalten ist, wird ausreichen.

+0

* 2) GETTEXT ist meiner Meinung nach eine Zeitverschwendung. * - In der Tat! – almosnow

1

Leider gettext funktionieren nicht gut und haben Probleme in verschiedenen Situationen wie auf verschiedenen Betriebssystemen (Windows oder Linux) und machen es Arbeit ist sehr schwierig.

Darüber hinaus müssen Sie viele Umgebungsvariablen und Domänen festlegen, und das hat keinen Sinn.

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

0

Sie können dies tun:

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

Sie würden eine Datei wie diese für jede Sprache. So verwenden Sie den Text:

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

Der Nachteil ist, dass, wenn Sie eine neue Konstante hinzufügen, haben Sie es zu tun für jede Sprachdatei. Wenn Sie einen vergessen, bricht Ihre Seite für diese Sprache. Das ist ein wenig unangenehm, aber es ist effizient, da es kein großes assoziatives Array erstellen muss und die Werte sogar inline werden.

Vielleicht könnte der Zugang verbessert werden, zum Beispiel:

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 haben immer noch das Array vermeiden und sich auf constant die Lookup zu tun, die ich nehme an teurer ist die Konstanten direkt als verwenden. Die obere Seite ist die Suche kann einen Fallback verwenden, wenn der Schlüssel nicht gefunden wird.

Verwandte Themen