tags:

views:

39

answers:

3

With PHP +5.3 and 6 comes a couple new i18n classes. One of them is the MessageFormatter Class which seems to be an incomplete idea. I'm hoping I'm just overlooking something.

The example given seems to show that if you ALREADY KNOW THE LANGUAGE YOU ARE USING, then this class will format the numbers for you correctly.

<?php
echo msgfmt_format_message("en_US", "{0,number,integer} monkeys on {1,number,integer} trees make {2,number} monkeys per tree", array(4560, 123, 4560/123));
echo msgfmt_format_message("de", "{0,number,integer} Affen auf {1,number,integer} Bäumen sind {2,number} Affen pro Baum", array(4560, 123, 4560/123));
?>

Which renders:

4,560 monkeys on 123 trees make 37.073 monkeys per tree
4.560 Affen auf 123 Bäumen sind 37,073 Affen pro Baum

Now if you already know the langauge (which is why you have to write it) then why don't you just use the number_format() function where you need proper numbers? Why do you need an entire class for this?

An example of doing something other than formatting numbers would really help.

+1  A: 

number_format only allows one to format... well, numbers -- and it will only format them as pure number.

On the other hand, the MessageFormater class does more than this :

  • It allows you to format numbers, yes ; but not only as "pure numbers", but also as (for instance) money
    • And both the format of a number, and the monerary unit, are different, depending on the locale.
    • For instance, in France, you'd use 1234,25 € ; while in the US, you'd use (forgive me if I'm wrong) something like $1,234.25
  • It allows you to format more than only numbers :
    • You can also format dates, for example
    • including the names of the days/month
  • And it does more than just formating some piece of data : it allows you to specify full strings, in which you use placeholders -- indicating which kind of data those should represent.
    • That last point is important when you are trying to translate/localize an application : formats changes, yes ; but positions of the data can also change, depending on the language.


This is great when you are developping an application, having someone else do the translations for you :

  • You code your application so it loads its translation strings from a file, that depends on the language
    • And you say, for each string, in which order you'll pass the data
  • Then, someone else takes your (english, for instance) translation file, and translate it to another language
    • Using the same placeholders as you did, for dynamic data
    • Placing them in a different order, if needed
  • Then, when your application is executed :
    • You load the right translation file,
    • You inject the data
    • And no-one has to care about formating the numbers/dates/... nor about the order of the data in the strings ; which is great ;-)


Also note that MessageFormater providers some additionnal features, like the MessageFormatter::parseMessage method, that does exactly the opposite.

I've never really used that one yet, though -- but it might prove useful in some situations, I bet.


Finally, you say this :

The example given seems to show that if you ALREADY KNOW THE LANGUAGE YOU ARE USING

Yes, MessageFormater expects that you know which language your application is currently renderring.

As a matter of fact, the role of the MessageFormater class is... to format messages -- nothing more.
But you have some other classes, that allow you to detect which language you should use ;-)

For instance, you might want to take a look at the Locale class -- the Locale::acceptFromHttp might especially interest you (quoting) :

Tries to find locale that can satisfy the language list that is requested by the HTTP "Accept-Language" header

Basically, this should help you detect which language the browser is "accepted" by your user is using -- which, most probably, will indicate which language/locale the current user is the most probably able to understand.

For instance, considering my browser is sending this for the Accept-language HTTP header :

fr,en;q=0.7,en-us;q=0.3

Locale::acceptFromHttp would indicate that I prefer the 'fr' locale -- which I do prefer ^^

Pascal MARTIN
U.S. money is right :)
Matchu
+1  A: 

I think you are confusing what the MessageFormatter does:

MessageFormatter is a concrete class that enables users to produce concatenated, language-neutral messages. The methods supplied in this class are used to build all the messages that are seen by end users.

That's quite different from a number_format, that only formats a number with grouped thousands.

Quoting further (emphasis mine):

MessageFormatter takes a set of objects, formats them, and then inserts the formatted strings into the pattern at the appropriate places. Choice formats can be used in conjunction with MessageFormatter to handle plurals, match numbers, and select from an array of items. Typically, the message format will come from resources and the arguments will be dynamically set at runtime.

If you need to compare this with a native function, then it's more like a locale-aware preg_replace_callback that can use number_format, date_format and fancy replacements like

"{0} resulted in {1,choice,0#no errors|1#single error|1<{1, number} errors}"

It should also be emphasized that MessageFormatter is just one subpackage completing a rather feature-rich I10n framework.

See this Article on DevZone about Internationalization in PHP 5.3.

Gordon
That gettext like string/plural sorting defiantly makes this class worth it. gettext is still so buggy and awkward in PHP that I still just use PHP-based language files and being able to use this class to choose plural forms would really help.
Xeoncross
@Xeoncross Use what fits. It's just one more package you *can* choose and use, like math vs bc_math or GD vs imagemagick.
Gordon
Your answer may not have been as good as Pascal's - but that example of the pluralizing is what I was looking for and the DevZone article was also very useful. Thanks!
Xeoncross
+1  A: 

Try reading the description of the format at the ICU website where it came from -- as usual for PHP, their documentation has no rationale, no organization, and utterly incomplete examples, but that doesn't mean the library is useless.

hobbs