PHP Intl now contains a new class that allows us to display arrays as locale-aware string lists – IntlListFormatter.
The purpose of it is relatively simple since it’s just a wrapper for ICU’s ListFormatter: take an array, pass a locale and display it as a string.
<?php
$formatter = new IntlListFormatter('en', IntlListFormatter::TYPE_AND, IntlListFormatter::WIDTH_WIDE);
echo $formatter->format([1, 2, 3]); //outputs "1, 2, and 3"
$formatter = new IntlListFormatter('en', IntlListFormatter::TYPE_AND, IntlListFormatter::WIDTH_SHORT);
echo $formatter->format([1, 2, 3]); //outputs "1, 2, & 3"
There are two optional parameters: conjunction type and width. The values accepted by these parameters are exposed as class constants and are a direct mapping to ICU’s accepted values:
- IntlListFormatter::TYPE_AND
- IntlListFormatter::TYPE_OR
- IntlListFormatter::TYPE_UNITS
- IntlListFormatter::WIDTH_WIDE
- IntlListFormatter::WIDTH_NARROW
- IntlListFormatter::WIDTH_SHORT
While this looks like a trivial feature that can be done in userland, things can get complicated if you need to support non-Latin locales. For example, for Japanese you don’t use a comma as a separator:
$formatter = new IntlListFormatter('ja_JP');
echo $formatter->format([1, 2, 3]); //outputs "1、2、3"
While you may say that’s a locale problem, we can observe differences between English locale too. For example, Oxford comma is used in en_US while en_GB is not:
$formatter = new IntlListFormatter('en_US');
echo $formatter->format([1, 2, 3]); //outputs "1, 2, and 3"
$formatter = new IntlListFormatter('en_GB');
echo $formatter->format([1, 2, 3]); //outputs "1, 2 and 3"
ICU constraints
Except for IntlListFormatter::TYPE_AND and IntlListFormatter::WIDTH_WIDE which work with all ICU versions supported by PHP, using the other ones with a lower version than ICU 67 will trigger an exception or fatal since they aren’t supported with those versions.
You can see this exception in action on 3v4l where the master branch is built with ICU 63.
It’s a small feature, but it represents my first real step into contributing to PHP in a more meaningful way. I hope you find it useful!