Форматирование данных

Для форматирования вывода Yii предоставляет класс, преобразующий данные в человеко-понятный формат. yii\i18n\Formatter это класс-помощник, который зарегистрирован как компонент приложения, по умолчанию под именем formatter.

Он предоставляет набор методов для форматирования таких данных как дата/время, числа и другие часто используемые в целях локализации форматы. Formatter может быть использован двумя различными способами.

  1. Напрямую, используя методы форматирования (все методы форматирования имеют префикс as):

    echo Yii::$app->formatter->asDate('2014-01-01', 'long'); // выведет: January 1, 2014
    echo Yii::$app->formatter->asPercent(0.125, 2); // выведет: 12.50%
    echo Yii::$app->formatter->asEmail('cebe@example.com'); // выведет: <a href="mailto:cebe@example.com">cebe@example.com</a>
    echo Yii::$app->formatter->asBoolean(true); // выведет: Yes
    // он также умеет отображать null значения:
    echo Yii::$app->formatter->asDate(null); // выведет: (not set)
    
  2. Используя метод format() и имя формата. Этот метод также используется в виджетах наподобие yii\grid\GridView и yii\widgets\DetailView, в которых вы можете задать формат отображения данных в колонке через конфигурацию виджета.

    echo Yii::$app->formatter->format('2014-01-01', 'date'); // выведет: January 1, 2014
    // вы также можете использовать массивы для настроек метода форматирования:
    // `2` это значение для $decimals параметра метода asPercent().
    echo Yii::$app->formatter->format(0.125, ['percent', 2]); // выведет: 12.50%
    

Все данные, отображаемые через компонент formatter, будут локализованы, если расширение PHP intl было установлено. Для этого вы можете настроить свойство locale. Если оно не было настроено, то в качестве локали будет использован язык приложения. Подробнее смотрите в разделе «интернационализация». Компонент форматирования будет выбирать корректный формат для даты и чисел в соответствии с локалью, включая имена месяцев и дней недели, переведённые на текущий язык. Форматирование дат также зависит от часового пояса, который будет взят из одноимённого свойства timeZone приложения, если не был задан явно. В свою очередь timeZone устанавливает / читает временную зону PHP.

Например, форматирование даты, вызванное с разной локалью, отобразит разные результаты::

Yii::$app->formatter->locale = 'en-US';
echo Yii::$app->formatter->asDate('2014-01-01'); // выведет: January 1, 2014
Yii::$app->formatter->locale = 'de-DE';
echo Yii::$app->formatter->asDate('2014-01-01'); // выведет: 1. January 2014
Yii::$app->formatter->locale = 'ru-RU';
echo Yii::$app->formatter->asDate('2014-01-01'); // выведет: 1 января 2014 г.

Обратите внимание, что форматирование может различаться между различными версиями библиотеки ICU, собранных с PHP, а также на основе того установлено ли расширение PHP intl или нет. Таким образом, чтобы гарантировать, что ваш сайт будет одинаково отображать данные во всех окружениях рекомендуется установить расширение PHP intl во всех окружениях и проверить, что версия библиотеки ICU совпадает. См. также: Настройка PHP окружения для интернационализации.

Отметим также, что даже если установлено расширение PHP intl, форматирование даты и времени для значений года >=2038 или <=1901 на 32-ух разрядных системах будет обращаться к реализации PHP, которая не обеспечивает локализованные имена месяца и дня, потому что в этом случае intl будет использовать 32-ух битный UNIX timestamp. На 64-битной системе intl formatter будет работать во всех случаях, если, конечно, intl был установлен.

Настройка форматирования

Форматы по умолчанию, используемые в методах форматирования, можно настраивать через свойства класса форматирования. Вы можете задать форматирование по умолчанию для всего приложения, настроив компонент formatter в вашей конфигурации приложения. Ниже приведён пример конфигурации. Чтобы узнать больше о доступных свойствах см. API документацию к классу Formatter и следующие подсекции.

'components' => [
    'formatter' => [
        'dateFormat' => 'dd.MM.yyyy',
        'decimalSeparator' => ',',
        'thousandSeparator' => ' ',
        'currencyCode' => 'EUR',
   ],
],

Форматирование значений даты и времени

Класс форматирования предоставляет различные методы для форматирования значений даты и времени. Например:

  • date — значение будет отформатировано как дата, например January 01, 2014.
  • time — значение будет отформатировано как время, например 14:23.
  • datetime — значение будет отформатировано как дата и время, например January 01, 2014 14:23.
  • timestamp — значение будет отформатировано как unix timestamp, например, 1412609982.
  • relativeTime — значение будет отформатировано как временной промежуток между заданной датой и текущим временем в человеко понятном формате, например: 1 час назад.
  • duration: значение будет отформатировано как продолжительность в человеко-понятном формате, например 1 день, 2 минуты.

Форматирование даты и времени для методов date, time и datetime может быть задано глобально через конфигурацию свойств форматирования $dateFormat, $timeFormat и $datetimeFormat.

По умолчанию, форматирование использует сокращенный формат, который интерпретируется по-разному в зависимости от активной в данный момент локали. Поэтому дата и время будут отформатированы наиболее часто используемым способом в стране и языке пользователя. Доступны 4 разных сокращенных формата:

  • short в локали en_GB отобразит, например, 06/10/2014 для даты и 15:58 для времени, в то время как
  • medium будет отображать 6 Oct 2014 и 15:58:42 соответственно,
  • long будет отображать 6 October 2014 и 15:58:42 GMT соответственно и
  • full будет отображать Monday, 6 October 2014 и 15:58:42 GMT соответственно.

Дополнительно вы можете задать специальный формат, используя синтаксис, заданный ICU Project, который описан в руководстве ICU по следующему адресу: http://userguide.icu-project.org/formatparse/datetime. Также вы можете использовать синтаксис, который распознаётся PHP-функцией date(), используя строку с префиксом php:.

// ICU форматирование
echo Yii::$app->formatter->asDate('now', 'yyyy-MM-dd'); // 2014-10-06
// PHP date() форматирование
echo Yii::$app->formatter->asDate('now', 'php:Y-m-d'); // 2014-10-06

Часовые пояса

Для форматирования значений даты и времени Yii будет преобразовывать их в соответствии с настроенным часовым поясом. Поэтому предполагается, что входные значения будут в UTC, если часовой пояс не был указан явно. По этой причине рекомендуется хранить все значения даты и времени в формате UTC, предпочтительно в виде UNIX timestamp, которая всегда в часовом поясе UTC по определению. Если входное значение находится в часовом поясе, отличном от UTC, часовой пояс должен быть указан явно, как в следующем примере:

// при условии Yii::$app->timeZone = 'Europe/Berlin';
echo Yii::$app->formatter->asTime(1412599260); // 14:41:00
echo Yii::$app->formatter->asTime('2014-10-06 12:41:00'); // 14:41:00
echo Yii::$app->formatter->asTime('2014-10-06 14:41:00 CEST'); // 14:41:00

Если часовой пояс форматтера не задан явно, используется часовой пояс приложения, то есть тот же, что задан в конфигурации PHP.

Примечание: Поскольку правила для часовых поясов принимаются различными правительствами и могут часто меняться, вероятно, информация в базе данных часовых поясов на вашем сервере не самая свежая. Как обновить базу вы можете узнать из руководства ICU. Смотрите также: Настройка вашего PHP окружения для интернационализации.

Форматирование чисел

Для форматирования числовых значений класс форматирования предоставляет следующие методы:

  • integer — значение будет отформатировано как целое число, например 42.
  • decimal — значение будет отформатировано как дробное число, состоящее из целого и дробной части, например: 2,542.123 или 2.542,123.
  • percent — значение будет отформатировано как процентное значение, например 42%.
  • scientific — значение будет отформатировано в научном формате, например: 4.2E4.
  • currency — значение будет отформатировано в денежном формате, например: £420.00. Обратите внимание, чтобы эта функция работала правильно, локаль должна включать в себя часть со страной, например: en_GB или en_US (потому что указание только языка будет неоднозначным в этом случае).
  • size — значение будет отформатировано как количество байт в человеко-понятном формате, например: 410 kibibytes.
  • shortSize — сокращённая версия size, например: 410 KiB.

Форматирование чисел может быть скорректировано с помощью дробного разделителя и тысячного разделителя, которые были заданы в соответствии с локалью.

Для более сложной конфигурации yii\i18n\Formatter::$numberFormatterOptions и yii\i18n\Formatter::$numberFormatterTextOptions могут быть использованы для настройки внутренне используемого класса NumberFormatter.

Например, чтобы настроить максимальное и минимальное количество знаков после запятой, вы можете настроить свойство yii\i18n\Formatter::$numberFormatterOptions как в примере ниже:

'numberFormatterOptions' => [
    NumberFormatter::MIN_FRACTION_DIGITS => 0,
    NumberFormatter::MAX_FRACTION_DIGITS => 2,
]

Остальное форматирование

Кроме форматирование даты, времени и чисел, Yii предоставляет набор других полезных средств форматирования для различных ситуаций:

  • raw — значение будет отображено как есть, это псевдо-форматирование, которое не даёт никакого эффекта, кроме значений null, которые будет отформатированы в соответствии с nullDisplay.
  • text — значением будет экранированный от HTML текст. Это формат по умолчанию, используемый в GridView DataColumn.
  • ntext — значением будет экранированный от HTML текст с новыми строками, сконвертированными в разрывы строк.
  • paragraphs — значением будет экранированный от HTML текст с параграфами, обрамлёнными в <p> теги.
  • html — значение будет очищено, используя HtmlPurifier, с целью предотвратить XSS атаки. Вы можете задать дополнительные параметры, такие как ['html', ['Attr.AllowedFrameTargets' => ['_blank']]].
  • email — значение будет отформатировано как ссылка mailto.
  • image — значение будет отформатировано как тег картинки.
  • url — значение будет отформатировано как ссылка .
  • boolean — значение форматируется как логическое. По умолчанию true будет отображено как Yes и false как No, переведенное на язык приложения. Вы можете настроить это через свойство yii\i18n\Formatter::$booleanFormat.

null значения

Для значений null в PHP класс форматирования будет отображать вместо пустой строки маркер, по умолчанию это (not set), переведенный на язык приложения. Вы можете настроить свойство nullDisplay для установки собственного маркера. Если вы не хотите обрабатывать null значения, то установите свойство nullDisplay в null.