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

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

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

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

php 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)

  1. Используя метод [[yii\i18n\Formatter::format()|format()]] и имя формата. Этот метод также используется в виджетах на подобии [[yii\grid\GridView]] и [[yii\widgets\DetailView]], в которых вы можете задать формат отображения данных в колонке через конфигурацию виджета.

php 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 было установлено. Для этого вы можете настроить свойство [[yii\i18n\Formatter::locale|locale]]. Если оно не было настроено, то будет использован [[yii\base\Application::language|язык приложения]] в качестве локали. Подробнее см. раздел интернационализация. Компонент форматирования будет выбирать корректный формат для даты и чисел в соответствии с локалью, включая имена месяца и дней недели, переведённые на текущий язык. Форматирование дат также зависит от [[yii\i18n\Formatter::timeZone|временной зоны]], которая также будет из свойства [[yii\base\Application::timeZone|timeZone]] приложения, если она не была задана явно.

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

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] (http://php.net/manual/ru/book.intl.php) или нет. Таким образом, чтобы гарантировать, что ваш сайт будет одинаково отображать данные во всех окружениях рекомендуется установить расширение PHP intl во всех окружениях и проверить, что версия библиотеки ICU совпадает. См. также: Настройка PHP окружения для интернационализации.

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

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

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

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

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

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

- [[yii\i18n\Formatter::asDate() date]] - значение будет отформатировано как дата, например January 01, 2014.
- [[yii\i18n\Formatter::asDatetime() datetime]] - значение будет отформатировано как дата и время, например January 01, 2014 14:23.
- [[yii\i18n\Formatter::asTimestamp() timestamp]] - значение будет отформатировано как unix timestamp, например, 1412609982.
- [[yii\i18n\Formatter::asRelativeTime() relativeTime]] - значение будет отформатировано как временной промежуток между заданной датой и
текущий временем в человеко понятном формате, например: 1 час назад.

Форматирование даты и времени для методов [[yii\i18n\Formatter::asDate()|date]], [[yii\i18n\Formatter::asTime()|time]] и [[yii\i18n\Formatter::asDatetime()|datetime]] может быть задано глобально через конфигурацию свойств форматирования [[yii\i18n\Formatter::$dateFormat|$dateFormat]], [[yii\i18n\Formatter::$timeFormat|$timeFormat]] и [[yii\i18n\Formatter::$datetimeFormat|$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 будет преобразовывать их в соответствии с [[yii\i18n\Formatter::timeZone|настроенной временной зоной]]. Поэтому предполагается, что входные значения будут в 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

Начиная с версии 2.0.1 стало возможно настраивать временную зону для предполагаемых timestamp, которые не включают в себя временную зону, как во втором примере в коде выше. Вы можете задать [[yii\i18n\Formatter::defaultTimeZone]] временной зоной, которую вы используете для хранения данных.

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

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

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

- [[yii\i18n\Formatter::asInteger() integer]] - значение будет отформатировано как целое число, например 42.
- [[yii\i18n\Formatter::asPercent() percent]] - значение будет отформатировано как процентное значение, например 42%.
- [[yii\i18n\Formatter::asScientific() scientific]] - значение будет отформатировано в научном формате, например: 4.2E4.
- [[yii\i18n\Formatter::asCurrency() currency]] - значение будет отформатировано в денежном формате, например: £420.00.
Обратите внимание, чтобы эта функция работала правильно, локаль должна включать в себя часть со страной, например: en_GB илиen_US потому что только язык будет неоднозначным в этом случае.
- [[yii\i18n\Formatter::asSize() size]] - значение будет отформатировано как количество байт в человеко понятном формате, например: 410 kibibytes.
- [[yii\i18n\Formatter::asShortSize() shortSize]] - сокращённая версия [[yii\i18n\Formatter::asSize()

Форматирование чисел может быть скорректирована с помощью [[yii\i18n\Formatter::decimalSeparator|дробного разделителя]] и [[yii\i18n\Formatter::thousandSeparator|тысячного разделителя]], которые были заданы в соответствии с локалью.

Для более сложной конфигурации, [[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 предоставляет набор других полезных средств форматирования для различных ситуаций:

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

null значения

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