In the process of learning the international component, we have already been exposed to the number formatting operation of NumberFormatter, which allows us to convert numbers into standard formats, currencies, local languages, etc. Today we are going to learn about another class MessageFormatter that is specially used for information formatting. It is mainly used for string operations.
MessageFormatter also follows the ICU specification. The bottom layer is the ICU operation in C, so there is not much difference in the usage of C-related code.
// 格式化 $fmt = new MessageFormatter("zh_CN", "{0,number,integer} 只猴子在 {1,number,integer} 颗树上,每只树上有 {2,number} 只猴子"); echo $fmt->format([4560, 123, 4560 / 123]), PHP_EOL; // 4,560 只猴子在 123 颗树上,每只树上有 37.073 只猴子 $fmt = new MessageFormatter("de", "{0,number,integer} Affen auf {1,number,integer} Bäumen sind {2,number} Affen pro Baum"); echo $fmt->format([4560, 123, 4560 / 123]), PHP_EOL; // 4.560 Affen auf 123 Bäumen sind 37,073 Affen pro Baum echo MessageFormatter::formatMessage("zh_CN", "{0,number,integer} 只猴子在 {1,number,integer} 颗树上,每只树上有 {2,number} 只猴子", [4560, 123, 4560 / 123]), PHP_EOL; // 4,560 只猴子在 123 颗树上,每只树上有 37.073 只猴子 echo MessageFormatter::formatMessage("de", "{0,number,integer} Affen auf {1,number,integer} Bäumen sind {2,number} Affen pro Baum", [4560, 123, 4560 / 123]), PHP_EOL; // 4.560 Affen auf 123 Bäumen sind 37,073 Affen pro Baum
See it? Similar to placeholders for precompilation operations in PDO. After calling the format() method, you can let the parameters in this method replace the content of the placeholder.
We can specify the parameter type and position used by the placeholder, {parameter subscript, type, extended type} This is the rule definition of the placeholder for formatting of this information data. It seems very simple, but in fact it has more functions, which we will see later.
However, it should be noted that it only supports numbers, dates, and text fragment types. There are official documents available in the reference link at the end of the article.
MessageFormatter::formatMessage() This static method can specify the language, prepared statements and replacement parameters at one time, without the need to instantiate and then call the format() method.
can be formatted. Of course, we can also deformat the relevant string according to the statement rules to obtain Parameter list corresponding to the placeholder.
// 根据格式化规则反向获取规则参数 $fmt = new MessageFormatter('zh_CN', "{0,number,integer} 只猴子在 {1,number,integer} 颗树上,每只树上有 {2,number} 只猴子"); $res = $fmt->parse("4,560 只猴子在 123 树上,每只树上有 37.073 只猴子"); var_export($res); // false echo "ERROR: " . $fmt->getErrorMessage() . " (" . $fmt->getErrorCode() . ")\n"; // ERROR: Parsing failed: U_MESSAGE_PARSE_ERROR (6) $fmt = new MessageFormatter('en_US', "{0,number,integer} monkeys on {1,number,integer} trees make {2,number} monkeys per tree"); $res = $fmt->parse("4,560 monkeys on 123 trees make 37.073 monkeys per tree"); var_export($res); // array ( // 0 => 4560, // 1 => 123, // 2 => 37.073, // ) $fmt = new MessageFormatter('de', "{0,number,integer} Affen auf {1,number,integer} Bäumen sind {2,number} Affen pro Baum"); $res = $fmt->parse("4.560 Affen auf 123 Bäumen sind 37,073 Affen pro Baum"); var_export($res); // array ( // 0 => 4560, // 1 => 123, // 2 => 37.073, // ) $fmt = MessageFormatter::parseMessage('de', "{0,number,integer} Affen auf {1,number,integer} Bäumen sind {2,number} Affen pro Baum", "4.560 Affen auf 123 Bäumen sind 37,073 Affen pro Baum"); var_export($fmt); // array ( // 0 => 4560, // 1 => 123, // 2 => 37.073, // )
Using the instantiated parse() method or directly using the static method MessageFormatter::parseMessage() can achieve such an operation.
It should be noted that for zh_CN, which is the Chinese language locale, this operation will cause problems. You can see the error message and error code through getErrorMessage() and getErrorCode(). You can see that for Chinese, the error message returned directly means that the parsing failed.
In the instantiated object, we can also dynamically modify the rule statement.
// 设置获取规则 $fmt = new MessageFormatter("zh_CN", "{0, number} 猴子在 {1, number} 颗树上"); echo "默认规则: '" . $fmt->getPattern(), PHP_EOL; // 默认规则: '{0, number} 猴子在 {1, number} 颗树上' echo "格式化结果:" . $fmt->format(array(123, 456)), PHP_EOL; // 格式化结果:123 猴子在 456 颗树上 $fmt->setPattern("{0, number} 颗树上有 {1, number} 猴子"); echo "新规则: '" . $fmt->getPattern(), PHP_EOL; // 新规则: '{0, number} 颗树上有 {1, number} 猴子' echo "新规则格式化结果: " . $fmt->format(array(123, 456)), PHP_EOL; // 新规则格式化结果: 123 颗树上有 456 猴子
Two very simple methods, setPattern() is used to set the formatting rules corresponding to the current instantiation, and getPattern() is used to obtain and view the formatting rules of the current instantiation object. After setting a new rule, format() or parse() will be executed according to the new rule statement.
As mentioned above, in addition to numbers, there can also be placeholders for date format, let’s demonstrate it.
echo MessageFormatter::formatMessage('zh_CN', '今天是 {3, date, full},当前时间为 {3, time, ::Hms}, 我要准备开始 {0} 了,今天要和 {2,number,integer} 人见面,还不能忘了要交 {1,number,currency} 元的电费', ['上班', 35.33, 25, new DateTime()]), PHP_EOL; // 今天是 2020年11月16日星期一,当前时间为 10:09:30, 我要准备开始 上班 了,今天要和 25 人见面,还不能忘了要交 ¥35.33 元的电费
In this statement, the order of the parameters we give is not in the order in which the placeholders appear in the statement. This has no effect. You only need to specify the parameter array subscript at the corresponding position, such as The first {3, date, full} specifies the 4th element (starting from 0) in the parameter array.
Date type and time type are both types that can be specified. Of course, we can also specify their date format. For example, for the second placeholder, we only display the current hour, minute, and second information.
If it is string information, then only a simple {0} is needed. Strings do not require too many type settings. Numeric types can be directly formatted into currency and other types, just like those types that can be specified in NumberFormatter we talked about before.
After reading this example, do you feel the power of this MessageFormatter? Don't worry, it has even more awesome capabilities.
For plural numbers, there is actually no such statement in Chinese grammar. For example, one cat is a cat and two cats are two cats.
echo MessageFormatter::formatMessage('en_US', 'I Have {0, plural, =0{no cat} =1{a cat} other{# cats}}', [0]),PHP_EOL; // I Have no cat echo MessageFormatter::formatMessage('en_US', 'I Have {0, plural, =0{no cat} =1{a cat} other{# cats}}', [1]),PHP_EOL; // I Have a cat echo MessageFormatter::formatMessage('en_US', 'I Have {0, plural, =0{no cat} =1{a cat} other{# cats}}', [2]),PHP_EOL; // I Have 2 cats
Although the parameter type plural means plural, we can actually think of it as a switch() statement. The number
echo MessageFormatter::formatMessage('zh_CN', '我{0, plural, =0{没有猫} other{有 # 只猫}}', [0]),PHP_EOL; // 我没有猫 echo MessageFormatter::formatMessage('zh_CN', '我{0, plural, =0{没有猫} other{有 # 只猫}}', [1]),PHP_EOL; // 我有 1 只猫 echo MessageFormatter::formatMessage('zh_CN', '我{0, plural, =0{没有猫} other{有 # 只猫}}', [2]),PHP_EOL; // 我有 2 只猫
\# is the original content of the corresponding parameter value. This set of syntax brings the MessageFormatter class to a higher level, and what’s more! Let’s take a look at this problem first:
echo MessageFormatter::formatMessage('en_US', 'I Have {0, plural, =0{no cat} =1{a cat} other{# cats}}', [-1]),PHP_EOL; // I Have -1 cats
The parameter is passed incorrectly, -1 cat is wrong, right? It doesn’t matter, there are other ways to solve this problem.
// 选择表达式 echo MessageFormatter::formatMessage('en_US', 'I Have {0, choice, 0 #no cats| 1 #one cat | 2 #{0, number} cats}', [-1]),PHP_EOL; // I Have no cats echo MessageFormatter::formatMessage('en_US', 'I Have {0, choice, 0 #no cats| 1 #one cat | 2 #{0, number} cats}', [0]),PHP_EOL; // I Have no cats echo MessageFormatter::formatMessage('en_US', 'I Have {0, choice, 0 #no cats| 1 #one cat | 2 #{0, number} cats}', [1]),PHP_EOL; // I Have one cat echo MessageFormatter::formatMessage('en_US', 'I Have {0, choice, 0 #no cats| 1 #one cat | 2 #{0, number} cats}', [2]),PHP_EOL; // I Have 2 cats echo MessageFormatter::formatMessage('en_US', 'I Have {0, choice, 0 #no cats| 1 #one cat | 2 #{0, number} cats}', [10]),PHP_EOL; // I Have 10 cats
You can see from the word choice that this is a selection-related grammar. The following parameters are actually an interval, representing which content is used within the range of <= 0 | 1 | >=2. In addition, a placeholder rule can also contain placeholder symbols.
Another eye-opener. There are actually no surprises in the first two parts of the article. After all, ordinary string replacement can be done, but it becomes more and more exciting as you go to the back.
Of course, there should be more related rule syntax, but these materials are very sparse, and neither the PHP official documents nor the ICU official documents have found much introduction.
So we still adopt the attitude of learning and understanding before we know that there is such a thing. In the future, we will find more interesting information before sharing and learning. We also hope that friends who have used it will leave a message and discuss it together!
Recommended learning: php video tutorial
The above is the detailed content of How to learn information formatting operations in PHP. For more information, please follow other related articles on the PHP Chinese website!