2010-05-10 12 views
25

Sto lavorando su un sito Web multilingue e sto prendendo in considerazione diversi approcci per renderlo multilingue. Le possibili alternative mi viene in mente sono:Approccio più efficiente per il sito Web PHP multilingue

  1. Le Gettext funzioni con generazione di file .po
  2. tavolo Uno MySQL con le traduzioni e un ID stringa univoca per ogni testo
  3. file PHP con array contenente le diverse traduzioni con gli ID stringa univoca

per quanto ho capito le funzioni Gettext dovrebbero essere più efficiente, ma la mia richiesta è che dovrebbe essere possibile modificare una stringa di testo nella lingua di riferimento originale (inglese) con le altre traduzioni di quella stringa tornano automaticamente in inglese solo perché sono cambiate un paio di parole. È possibile con Gettext?

Qual è la soluzione meno impegnativa?
Sta usando le funzioni Gettext oi file PHP con array più o meno altrettanto impegnativi di risorse?
Qualche altro suggerimento per soluzioni più efficienti?

risposta

26

alcune considerazioni:

1. Traduzioni
che farà le traduzioni? Persone che sono anche collegate al sito? Un'agenzia di traduzione? Quando usi Gettext, lavorerai con i file 'pot' (.po). Questi file contengono l'ID del messaggio e la stringa del messaggio (la traduzione). Esempio:

msgid "A string to be translated would go here" 
msgstr ""

Ora, questo sembra più che bene e comprensibile per chiunque abbia bisogno di tradurre questo. Ma cosa succede quando usi parole chiave, come suggerisce Mike, invece di frasi complete? Se qualcuno ha bisogno di tradurre un msgid chiamato "address_home", non ha idea se questo dovrebbe essere un header "Home address" o che sia una frase completa. In questo caso, assicurarsi di aggiungere commenti al file giusto prima di chiamare la funzione gettext, in questo modo:

/// This is a comment that will be included in the pot file for the translators 
gettext("ready_for_lost_episode"); 

Utilizzando xgettext --add-comments=/// durante la creazione dei file .po aggiungerà questi commenti. Tuttavia, non penso che Gettext sia usato in questo modo. Inoltre, se è necessario aggiungere commenti con ogni testo che si desidera visualizzare a) probabilmente si commette un errore ad un certo punto, b) l'intero script verrà comunque riempito con i testi, solo in forma di commento, c) i commenti devono essere posizionati direttamente sopra la funzione Gettext, che non è sempre comoda, a seconda della posizione della funzione nel codice.

2.Manutenzione
Una volta che il tuo sito cresce (anche oltre) e i tuoi file di lingua insieme, potrebbe essere piuttosto difficile mantenere tutte le diverse traduzioni in questo modo. Ogni volta che aggiungi un testo, devi creare nuovi file, inviare i file ai traduttori, ricevere i file, assicurarti che la struttura sia ancora intatta (i traduttori desiderosi sono sempre felici di tradurre anche la sintassi, rendendo l'intero file inutilizzabile :)) e termina con l'importazione delle nuove traduzioni. È fattibile, certo, ma sii consapevole dei possibili problemi a questo proposito con siti di grandi dimensioni e molte lingue diverse.


Un'altra opzione: combinare il 2 ° e 3 ° alternativa:

Personalmente, trovo più utile per gestire la traduzione utilizzando un (semplice) CMS, mantenendo le variabili e le traduzioni in un database ed esportazione i testi pertinenti ai file in lingua:

  1. aggiungere variabili al database (ad esempio id, pagina, variabile);
  2. aggiungere traduzioni a queste variabili (ad esempio id, varId, lingua, traduzione);
  3. selezionare le variabili e le traduzioni rilevanti, scriverle in un file;
  4. include il file di lingua pertinente nel tuo sito;
  5. creare la propria funzione per visualizzare un testo variabili:

text('var'); o forse qualcosa di simile __('faq','register','lost_password_text');

punto 3 può essere semplice come la selezione tutte le variabili e le traduzioni rilevanti dal database, mettendoli in un array e scrivere l'array serializzato su un file.

Vantaggi:

  1. manutenzione. Mantenere i testi può essere molto più semplice per i grandi progetti. Puoi raggruppare le variabili per pagina, sezioni o altre parti all'interno del tuo sito, semplicemente aggiungendo una colonna al tuo database che definisce a quale parte del sito appartiene questa variabile. In questo modo puoi rapidamente visualizzare un elenco di tutte le variabili utilizzate ad es. la pagina delle domande frequenti

  2. Traduzione. È possibile visualizzare la variabile con tutte le traduzioni di tutte le lingue diverse su una singola pagina. Questo potrebbe essere utile per le persone che possono tradurre testi in più lingue allo stesso tempo. E potrebbe essere utile vedere altre traduzioni per avere un'idea del contesto in modo che la traduzione sia il migliore possibile. Puoi anche interrogare il database per scoprire cosa è stato tradotto e cosa no. Forse aggiungi timestamp per tenere traccia di possibili traduzioni obsolete.

  3. Accesso. Questo dipende da chi tradurrà. Puoi avvolgere il CMS con un semplice accesso per consentire l'accesso alle persone da un'agenzia di traduzione, se necessario, e consentire loro solo di cambiare alcune lingue o persino alcune parti del sito. Se questa non è un'opzione, è comunque possibile inviare i dati a un file che può essere tradotto manualmente e importarlo in un secondo momento (sebbene ciò potrebbe comportare gli stessi problemi menzionati in precedenza). Puoi aggiungere una delle traduzioni già presenti (inglese o un'altra lingua principale) come contesto per il traduttore.

Tutto sommato, penso che scoprirete che avrete un maggiore controllo sulle traduzioni in questo modo, specialmente nel lungo periodo. Non posso dirvi nulla sulla velocità o l'efficienza di questo approccio rispetto alla funzione gettext nativa. Ma, a seconda delle dimensioni dei file di lingua, non penso che sarà una grande differenza. Se si raggruppano le variabili per pagina o sezione, è sempre possibile includere solo le parti richieste.

+0

Grazie per la risposta completa! Facciamo un paio di traduzioni noi stessi, ma il resto sarà fatto da un'agenzia di traduzioni. Ero a conoscenza del problema con l'uso delle chiavi in ​​gettext, ma se avessi scelto quell'approccio probabilmente avrei creato il mio parser per creare i file PO usati dai traduttori dai file PO creati da xgettext in modo da combinare l'inglese con la lingua tradotta invece delle chiavi. Ho pensato di utilizzare DB, ma mi sembra inefficiente effettuare richieste al DB per quello che praticamente può essere considerato come contenuto statico. – alexteg

+0

Stavo pensando a una soluzione con DB nel backend per la creazione di un frontend per i traduttori, ma poi la generazione di file PO statici-> MO-file o array PHP nei file di lingua inclusi a seconda della lingua richiesta. Quando si tratta di prestazioni, sembra ancora dalla mia ricerca che i file PO siano i più efficienti, dal momento che sono memorizzati nella cache, tradotti automaticamente (file MO) e su un livello inferiore rispetto a ciò che può essere scritto in PHP. Tuttavia, eseguirò alcuni test delle prestazioni sulle diverse tecniche e pubblicherò qui presto. – alexteg

3

Invece di dover utilizzare il testo inglese come i tasti si può arbitrariamente fare questo, ma anche di fornire traduzioni in inglese, vale a dire

chiave gettext è 'ciao'

Allora avete le vostre varie traduzioni di questo linguaggio e una traduzione inglese di questo è anche 'ciao', quindi se vuoi aggiornare la versione inglese della stringa puoi lasciare la chiave da solo e aggiornare la traduzione inglese.

+0

Sembra una buona idea. Ma la funzione gettext è l'approccio che richiede meno risorse o esiste una soluzione migliore? – alexteg

+0

Non ho mai investito troppo tempo in questo perché gettext è sempre stato abbastanza veloce anche per alcuni dei grandi siti in cui sono stato coinvolto, ma a un rapido sguardo a un articolo di benchmarking: http: //mel.melaxis. com/devblog/2006/04/10/benchmarking-php-localization-is-gettext-fast-enough/ sembra suggerire alcune idee sull'efficienza delle risorse. – Pollett

+0

Bene, grazie per l'aiuto e il collegamento. Penso che userò l'approccio gettext con le chiavi come traduzione originale allora. – alexteg

13

Dopo alcune prove ho finalmente deciso di andare più o meno con le linee della combinazione di Alecs della seconda e della terza alternativa.

problema Gettext
Ho cercato di impostare l'intero gettext sistema prima di provarlo, ma si è rivelato essere molto più complicato poi ho pensato. Il problema è che i sistemi Windows e Unix utilizzano nomi di parole diversi per setlocale(). Per il momento sto utilizzando il mio server di sviluppo su Windows con Wamp, mentre il sito finale verrà eseguito su Linux. Dopo aver passato un paio di dozenguides, forums, questions ecc. E riavviare il server dopo ogni modifica. Non riuscivo a installarlo correttamente in nessun modo semplice sembrava. Inoltre gettext non è protetto da thread, per aggiornare il file della lingua il server deve essere riavviato o è necessario utilizzare a hack, non esiste un modo semplice per gestire versioni diverse dei file di lingua o gestire il testo inglese originale senza modificare la fonte o utilizzare Mike , che come sottolineato da Alec non è ottimale.

Soluzione
Così ho finito con quello che penso è la soluzione migliore in base a Alecs risposta:

  • Salva tutte le traduzioni in un DB con i campi; lingua, pagina, var_key, versione, revisione e last_modified_time - dove la versione corrisponde alle versioni della traduzione originale (inglese), mentre la revisione consente al traduttore di modificare/correggere le traduzioni finalizzate all'interno di una versione.
  • Utilizzare un tipo di CMS per la traduzione, che è collegato al DB e gestisce diverse versioni e consente una facile panoramica di quali lingue sono tradotte, in quale versione e quanto complete sono le traduzioni.
  • Quando una revisione di una versione è finalizzata, vengono generati file di cache - ogni file contiene una matrice con solo il var_key e la traduzione del testo per una lingua e una pagina e sono denominati con i nomi ISO 639-1 delle lingue e il nome della pagina come: lang/en_index.php Questi file di linguaggio vengono quindi semplicemente inclusi e racchiusi in una funzione t ($ var_key) che consente di utilizzare il DB durante lo sviluppo, mentre poi viene modificato per utilizzare solo i file di cache.

prestazioni
non ho mai avuto in giro per testare gettext, ma secondo the link Mike posted la differenza di prestazioni tra l'utilizzo di un array e gettext è del tutto accettabile per me per i benefici che un sistema personalizzato dà come descritto sopra. Tuttavia, ho confrontato l'utilizzo di un array con 20 stringhe di testo tradotte in un array rispetto al recupero delle stesse 20 stringhe di testo da un MySQL DB. Si è scoperto che l'utilizzo di un array incluso da un file era pari a 6 volte più veloce rispetto al recupero di tutte le 20 stringhe allo stesso tempo dal DB MySQL.Non è stato un vero punto di riferimento scientifico ei risultati potrebbero sicuramente variare su diversi sistemi e configurazioni, ma mostra chiaramente esattamente quello che mi aspettavo - che sarebbe molto più lento usare un DB piuttosto che usare direttamente un array, ecco perché ho scelto di generare cache -file per l'array invece di usare il DB.

Come confronto ho anche verificato quanto fosse veloce emettere solo echi semplici con lo stesso testo. Si è rivelato essere circa 20 volte più veloce rispetto all'utilizzo di array da un file incluso, ma bene - quindi non è possibile tradurre senza avere versioni diverse della pagina per lingue diverse, che sfidano lo scopo delle pagine dinamiche. Quindi è meglio usare anche a good cachesystem.

prestazioni file di origine di prova:
PHP: http://pastie.org/964082
MySQL tabella: http://pastie.org/964115
E non è certo perfetto, ma almeno crea un'idea circa le differenze di prestazioni.

+0

I file di piccole dimensioni saranno più efficienti della lettura da un database. Questo perché sono memorizzati nella cache su più livelli, dalla cache di sistema alla cache PHP. Le query del database non vengono memorizzate nella cache, poiché si presume che il database cambi. –

+0

@ Michał Leon: commento molto utile! Quanto kb o mb è un file 'piccolo'? Dove posso vedere/impostare quei valori di incassatura dei file? – CoR

Problemi correlati