After I recently tackled this (12 languages and counted) in a production system and ran into some serious performance issues, I propose a hybrid system.
1) Save the language strings and translations in the database - this will simplify the interaction with the / update / remove elements and will become part of your regular backup routines.
2) Download the languages into flat files on the server and cross them out if necessary to display on the page.
There are many advantages - mostly fast! I am not dealing with communication overhead for MySQL or any traffic slowdown during transmission. (especially important if your database server is not localhost).
It will also make it very easy to use. Store the data from your database in a file as a serialized php and GZIP array so that the contents of the file are reduced due to lack of memory (this also makes it faster in my benchmarking).
Example:
$lang = array( 'hello' => 'Hallo', 'good_morning' => 'Guten Tag', 'logout_message' = > 'We are sorry to see you go, come again!' ); $storage_lang = gzcompress( serialize( $lang ) );
When the user boots your system for the first time, execute file_exists('/files/languages/my_page.de') . If the file exists, download the contents, un-gzip and un-serialize, and it is ready to go.
Example
$file_contents = get_contents( 'my_page.de' ); $lang = unserialize( gzuncompress( $file_contents ) );
As you can see, you can make caching specific to every page in the system to reduce overhead and use the file extension to indicate the language ... (my_page.en, my_page.de, my_page.fr)
If the file does NOT exist, then query the database, build your array, serialize it, gzip and write the missing file - at the same time, you just created the array that the page needs to continue displaying the page, and everyone is happy.
Finally, it allows you to create update pages that are accessible to non-programmers, but you also control when changes appear, deciding when to delete cache files so that they can be restored by the system.
Warnings and Errors
When I stored everything in the database directly, we hit some BASIC slowdowns when our traffic became spiked.
Trying to keep them in flat file arrays was just such a big problem, because updates were painful and error prone.
Non-gzip, which compresses the contents of cache files, forced language systems to be about 20% slower in my tests.
Make sure that all fields in your database containing languages are set to UTF8-general-ci (or at least one of the UTF8 options, I believe that I use general-ci for most users). If you do not, you will not be able to store non-encoded characters in your database (e.g. Chinese, Japanese, etc.)
Extension: In response to the comment below, be sure to set up database tables with page-level language strings.
id string page global 1 hello NULL 1 2 good_morning my_page.php 0
Everything that is displayed in the header or footer may have a global flag that will be requested in each cache file created, otherwise request them on the page for your system to respond.