Перейти к содержимому

Дата, число и HTML в свойствах - хранение, вывод, фильтр

Разбираем три типа значений, на которых чаще всего спотыкаются: дату, число и текст с разметкой. Хранятся они совсем не так, как выглядят в форме правки.

Решение

Смотрим, что лежит в свойстве-дате:

$res = CIBlockElement::GetList([], ['IBLOCK_ID' => 5, 'ID' => $elementId], false, false,
['ID', 'PROPERTY_EVENT_DATE']);
$row = $res->Fetch();
var_dump($row['PROPERTY_EVENT_DATE_VALUE']); // строка в формате сайта
echo MakeTimeStamp($row['PROPERTY_EVENT_DATE_VALUE']); // перевод в метку времени

Дата хранится строкой в формате сайта, а не числом. Отсюда правило: сравнивать и считать разницу можно только после перевода в метку времени, а сравнение строк даёт порядок по первому символу.

Выводим текст с разметкой:

$prop = $row['PROPERTY_DETAILS_VALUE'];
// значение приходит парой: сам текст и признак его вида
echo $prop['TYPE'] === 'HTML' ? $prop['TEXT'] : nl2br(htmlspecialcharsbx($prop['TEXT']));

Значение приходит парой из текста и признака вида. Вывод без проверки признака даёт либо разметку в виде тегов на экране, либо чужой код на странице, и оба случая одинаково нежелательны.

Сортируем по числовому свойству:

$res = CIBlockElement::GetList(['PROPERTY_POWER' => 'ASC'], ['IBLOCK_ID' => 5],
false, false, ['ID', 'NAME', 'PROPERTY_POWER']);
// значения свойств хранятся строками: 10 окажется раньше 9
// для честной сортировки заводят свойство типа число

Значения свойств хранятся строками, и сортировка идёт как по тексту. Число десять встаёт раньше девяти, и лечится это отдельным числовым типом свойства, а не приведением при выводе.

Фильтруем по диапазону:

$filter = ['IBLOCK_ID' => 5,
'>=PROPERTY_EVENT_DATE' => '01.09.2026',
'<=PROPERTY_EVENT_DATE' => '30.09.2026',
'>PROPERTY_POWER' => 100,
];
// приставки работают и со свойствами, и с полями элемента
// дата в фильтре указывается в формате сайта, а не в формате базы

Границы диапазона задаются приставками к имени свойства. Даты в фильтре передаются в формате сайта, а не в произвольном: строка другого формата даёт пустую выборку без всякой ошибки.

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

Пустое значение и записанный в свойство ноль - это совсем разные вещи. Свойство с нулём заполнено, свойство без значения не существует в таблице, и фильтр «не равно» ведёт себя на них по-разному.

Тип свойства выбирают до его первого заполнения, а не после. Смена типа у заполненного свойства теряет значения, и перенос делают скриптом с записью в новое свойство.

Типичные проблемы

Сортировка по числу даёт странный порядок.

Значение свойства хранится строкой, и сравнение всегда идёт как по обычному тексту. Для честного порядка заводят свойство числового типа заранее, до заполнения.

На странице видны теги вместо оформления.

Текст с разметкой выведен на странице как самая обычная строка. Вид значения приходит вместе с текстом, и его нужно каждый раз проверять.

Фильтр по дате ничего не находит.

Дата передана в фильтр в формате, отличном от принятого на самом сайте. Сравнение строк при этом просто ничего в базе не находит.

Разница между датами считается неверно.

Строки с датами сравниваются напрямую, без перевода в метку времени. Формат даты сайта для такого прямого сравнения строк не годится.

Фильтр «не равно» пропускает элементы.

У части элементов этого значения нет вовсе, а вовсе не записан ноль. Отсутствующее значение в такое условие отбора попросту не попадает.

Частые вопросы

Как хранить дату со временем?

Типом «дата со временем»: он хранит и время тоже. Обычная дата время не сохраняет и обрезает его при записи.

Чем текст отличается от текста с разметкой?

Признаком вида у значения. Он же решает, как значение выводить и как чистить перед показом.

Можно ли фильтровать по части строки?

Да, приставкой поиска по вхождению. На больших каталогах такой отбор дорог и требует указателя в базе.

Что делать с диапазоном цен в фильтре?

Брать цену из торгового каталога, а не из свойства. Цена в свойстве не участвует в расчётах и скидках.

Смежное

Первоисточник