Codice PHP:
<?php
/**
Per funzionare tale script 'multilang.php' necessita di una directory chiamata 'locales',
che contiene a sua volta la cartella de_DE, una en_US ed una it_IT. Ognuna di queste poi
conterrà una directory detta LC_MESSAGES dove vanno inseriti i file .po e .mo
Inoltre tale script necessita anche che tutti i locale siano installati nel sistema.
Posso controllare questo con la shell, dando:
locale -a
Oppure con PHP grazie alla funzione system() così che controllo tutti i locale
installati sul server in locale:
echo system('locale -a');
*/
// Ricordarsi di aggiungere sempre e solo .utf8 (con il punto) e NON ad es. UTF-8!!!
if ( isset ($_GET['lang']) )
{
switch ( $_GET['lang'] )
{
case 'it':
$locale = 'it_IT.utf8';
break;
case 'en':
$locale = 'en_US.utf8';
break;
case 'de':
$locale = 'de_DE.utf8';
break;
}
}
else
{
// default italiano
$locale = 'it_IT.utf8';
}
/**
Per mostrare le bandierine, creo una directory, flags, con le bandiere chiamate
semplicemente it.gif, en.gif, it.gif ecc. Importante che qui gli indici nei 2
array associativi devono essere uguali, per funzionare con le pagine
dove includo questo file, multilang.php. Infatti uso questo snippet di codice per
far apparire le bandiere e cambiare la lingua del sito al clic dell'utente su quella
scelta:
<div id="flags">
<?php
foreach ( $languages as $k => $v )
{
?>
<a href="?lang=<?php echo $k; ?>"><img src="flags/<?php echo $flags[$k]; ?>.gif" alt="<?php echo $v; ?>" title="<?php echo $v; ?>" /></a>
<?php
}
?>
</div>
*/
$languages = array('it' => 'Italiano', 'en' => 'English', 'de' => 'Deutsch');
$flags = array('it' => 'it', 'en' => 'us', 'de' => 'de');
// la directory locales, con dentro le directory de_DE, en_US, it_IT
$locales_path = 'locales';
// questo rappresenta il nome dei file .po/.mo
$domain = 'messages';
// Posso anche scrivere quanto indicato qui sotto, come alternative:
// putenv('LANGUAGE=' . $locale);
// putenv('LANG=' . $locale);
// notare che la costante LANGUAGE o LANG oppure LC_ALL va sempre tra virgolette
// perché fa parte dell'argomento della funzione putenv(), unita
// con il . (punto) di concatenazione alla variabile $locale
putenv('LC_ALL=' . $locale);
setlocale(LC_ALL, $locale);
// estraggo con substr() i primi 5 caratteri dai $locale per entrare
// nella directory giusta, cioè it_IT, en_US, de_DE, che contiene i files .mo
$locale_extr = substr($locale, 0, 5);
$filename = "$locales_path/$locale_extr/LC_MESSAGES/$domain.mo";
// prendo nota di ogni modifica fatta al file .mo con la funzione filemtime()
// sarebbe ad es:
// 1398944365
$mtime = filemtime($filename);
// il nuovo unico file .mo
// sarebbe ad es:
// locales/de_DE/LC_MESSAGES/messages_1398944365.mo
$filename_update = "$locales_path/$locale_extr/LC_MESSAGES/{$domain}_{$mtime}.mo";
/**
libero la cache. Infatti gettext() o il suo alias _(), tiene
nella cache di Apache gli originali file .mo, , di conseguenza se
faccio delle modifiche, sempre tramite Poedit, ai file .po/, queste
non si vedrebbero: cioè se cambio/aggiungo qc. alle
traduzioni (con Poedit nei file .po) non verrebbero mostrate.
Se si ha accesso al server, tipo in locale, (non online su hosting condivisi, come
altervista.org) si può riavviare il server, oppure bisogna cambiare il dominio, cioè
il nome del file .po/.mo, nelle funzioni bindtextdomain(), e poi textdomain().
*/
// entro nella directory con dirname() che mi restituisce il path al file $filename_update
// qui ritorna ad es:
// locales/de_DE/LC_MESSAGESmessages_1398944365.mo
$current_dir = dirname($filename_update);
// scansiono la directory precedente con scandir() che ritorna un array con tutti i file
// presenti: posso stampare a video il contenuto con: print_r($dir); ma non con echo!!!
// ottenendo quanto segue:
// Array ( [0] => . [1] => .. [2] => messages_1398944365.mo [3] => messages.mo [4] =>
// messages.po )
$dir = scandir($current_dir);
// scorro l'array restituito da scandir() con un loop foreach() e cancello il file
// cercato sopra, con la funzione unlink()
foreach ( $dir as $file )
{
if ( in_array($file, array('.', '..', "{$domain}.po", "{$domain}.mo", "{$domain}_{$mtime}.mo")) )
continue;
// cancello il vecchio file .mo che non mi serve più, ad es:
// locales/de_DE/LC_MESSAGES/messages_1399113252.mo
unlink($current_dir . '/' . $file);
//echo($current_dir . '/' . $file) . '<br />';
}
// se il file .mo non è stato creato,
// ad es: messages_1398944365.mo, allora copio quello originale
if ( !file_exists($filename_update) )
{
copy($filename, $filename_update);
}
// ottengo ora il nuovo nome di $domain (messages) così che il
// caching non può avvenire, sarebbe ad es:
// messages_1398944365
$domain_update = "{$domain}_{$mtime}";
// Per controllare il nuovo dominio
//echo $domain_update . '<br /><br />';
// bindtextdomain($domain, './locales');
// oppure usare dirname() con la costante FILE come indicato qui sotto,
// per trovare il path corretto, cioè assoluto, alla cartella che ho chiamato: locales
bindtextdomain($domain_update, dirname(__FILE__) . '/locales');
textdomain($domain_update);
echo gettext('traduzione') . '<br />';
echo _('casa'). '<br />';