Hi Guys,

I'm just wondering is there is a good Zend Framework-based methodology for storing multi-lingual content in a database?

I know that there are several structures for doing this kind of thing, including tables of strings that include language identifiers and such like, but these can often be complex and hard to model.

What I've done in the past is create some custom UDF functions in MySQL to pack multi-lingual content into a single field.

I would do something like:
INSERT INTO table SET field=LANG_PACK('en', 'Hello', 'fr', 'Bonjour');

I could then do:
SELECT LANG_EXTRACT(field, 'fr', 'en') FROM table;
which would give me back 'Bonjour'; or

SELECT LANG_EXTRACT(field, 'de', 'en', 'fr') FROM table;
which would give me back 'Hello' as no 'de' translation was found.

In the past, I've generally integrated the call to LANG_EXTRACT into an API call in my db layer so when extracting the language for the current locale the app is running in is trivial - so in ZF parlance something similar to this:

$db->select()->from('table', $db->langField('field'));
(where $db->langField() would returns a Zend_Db_Expr).

This has the advantage that only the correct language comes out of the database layer, and there is no logic required in the application.

As the MySQL functions are written in C and the packed language format includes a header which contains exact byte locations of the substring we want and thus can return the data quickly. It also handles "falling back" to 2nd or thrid choice of language if the data is not present in the preferred language.

Personally I really like the approach of dumping this logic into the db layer. It keeps the application logic quite simple. Some other MySQL functions allow for full extraction of the data in XML (LANG_XML()) format and thus allow for the creation of an editing interface that shows all languages (e.g. as tabs). Other functions include LANG_UPDATE() and LANG_PACK_XML() to perform what their name suggests.

Now all of this is very non-standard. It works for me and I find it quite efficient and effective for my needs... there are however several disadvantages: 1. Indexing: The db layer cannot index this content particurly well, and comparing the result of a function is not that efficient as it needs a full table scan. 2. It requires custom functions to be compiled and installed on the db server. While this is quite simple, it's obviously an sysadmin overhead.


So my basic question is, is there a standard way to do this kind of thing in ZF?

Perhaps there is a construct in the ZF db layer (or such a construct could be create) to store the multilingual data in XML and extract out the specific string from the XML semi-transparently?

This is kind of the opposite to Zend_Db_Expr where you define something that should be passed to the DB directly. I'd propose a Zend_Db_Filter which would have a way to know what expression to select ($f->getExpr()) and know that before the data is returned to the caller, it should be filtered ($fiels = $f->filter($field)).

(This kind of filter could be useful for other things too, e.g. for creating an image object from raw image data etc.)

Going back to my above example:
$db->select()->from('table', $db->langField('field'));

$db->langField() would return a Zend_Db_Filter object and the field itself would just store e.g. XML.


I don't want to ramble on here and go off on too many tangents, so I'm just really canvassing ideas/opinions as to how this kind of thing could be done and what improvements can be made to ZF to support this.

Thoughts?

Col




--

Colin Guthrie
gmane(at)colin.guthr.ie
http://colin.guthr.ie/

Day Job:
  Tribalogic Limited [http://www.tribalogic.net/]
Open Source:
  Mandriva Linux Contributor [http://www.mandriva.com/]
  PulseAudio Hacker [http://www.pulseaudio.org/]
  Trac Hacker [http://trac.edgewall.org/]

Reply via email to