Article:
  Internationalization and Localization with PHP
Subject:   Creating the arrays from language config files
Date:   2004-02-15 20:24:50
From:   kenr@nodots.net
I found the article very helpful--the app I am working on needs to be able to run on plain vanilla PHP, i.e., no gettext() functionality, but I wanted to be able to use gettext() if it is available.


So, I created the standard gettext() directory structure:


/locale/<LANGUAGE_STRING>/LC_MESSAGE


Under LC_message I created pipe-delimited files called messages.txt with the word or phrase pairings. For example:


// computer terms
computer|computadora
hard drive|disco duro
monitor|monitor


I then wrote a PHP script to parse this into an array of the format suggested in the article and put it in a file called "locale.inc.php" that I include in my top-level include file. (I didn't want to have to parse the file every time I needed a translation for performance reasons) The script is designed to run as a cron job so any changes to the text files are reflected in the array. Here is the script:


<?php


/* $Id$
*
* Author: Ken Riley <kenr@nodots.com>
* Copyright (C) 2004 Nodots Development, Inc. All Rights Reserved.
* <http://www.nodots.com/>
*
* Description: Reads pseudo-i18n files and generates arrays. Designed to run
* as a cron process.
*/


include('include/GLOBALS.inc.php');
$dh = dir(LOCALE_DIR);
$outFile = BASE_DIR."/include/locale.php";
$localeFile = fopen($outFile,"w+");
writeHeader($localeFile);
$languageCt = 0;


while (false !== ($file = $dh->read())) {
if ($file != "." && $file != "..") {
$languageFile = LOCALE_DIR."/".$file."/LC_MESSAGES/messages.txt";

fwrite($localeFile,"\t'$file'=> array(\n");
$fh = fopen($languageFile,"r");
$s = "";
while ( feof($fh) === false ) {
$line = chop(fgets($fh));
if ( substr($line,0,2) != "//" and $line != "" ) {


$translation = explode("|",$line);
$english = $translation[0];
$translated = $translation[1];
$s .= "\t\t'$english' => '$translated',\n";
}


}
$strSize = sizeof($s);
$strSize = $strSize - 2;
$cleanS = substr($s,0,$strSize);
$cleanS .= "\n\t),";
fwrite($localeFile,$cleanS);
$languageCt++;
fclose($fh);
}
}


writeFooter($localeFile);
$dh->close();


function writeHeader($fh) {
$timestamp = date("d-m-Y G:i:s");
$headerString = "<?php\n";
$headerString .= "// created ".$timestamp." by buildLanguageFile.php\n\n";
$headerString .= "\$messages = array (\n";
fwrite($fh,$headerString);
}


function writeFooter($fh) {
$footerString = ");\n";
$footerString .= "?>";
fwrite($fh,$footerString);


}


?>


I then added the author's msg($s) function into my top-level include file. If I have a client with access to gettext(), I just modify that function to use gettext() rather than the array.


So, you have simple text files for the translator, a process for automatically slurping those into an array, and a clear path to full-fledged i18n support in your ap.


Provecho,


Ken Riley
Nodots Development, Inc.