Дата, число и 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,];// приставки работают и со свойствами, и с полями элемента// дата в фильтре указывается в формате сайта, а не в формате базыГраницы диапазона задаются приставками к имени свойства. Даты в фильтре передаются в формате сайта, а не в произвольном: строка другого формата даёт пустую выборку без всякой ошибки.
Формат хранения стоит помнить и при выгрузке в чужие системы. Дата уезжает строкой, число уезжает строкой, и принимающая сторона разбирает их по своим правилам, а не по вашим ожиданиям.
Пустое значение и записанный в свойство ноль - это совсем разные вещи. Свойство с нулём заполнено, свойство без значения не существует в таблице, и фильтр «не равно» ведёт себя на них по-разному.
Тип свойства выбирают до его первого заполнения, а не после. Смена типа у заполненного свойства теряет значения, и перенос делают скриптом с записью в новое свойство.
Типичные проблемы
Сортировка по числу даёт странный порядок.
Значение свойства хранится строкой, и сравнение всегда идёт как по обычному тексту. Для честного порядка заводят свойство числового типа заранее, до заполнения.
На странице видны теги вместо оформления.
Текст с разметкой выведен на странице как самая обычная строка. Вид значения приходит вместе с текстом, и его нужно каждый раз проверять.
Фильтр по дате ничего не находит.
Дата передана в фильтр в формате, отличном от принятого на самом сайте. Сравнение строк при этом просто ничего в базе не находит.
Разница между датами считается неверно.
Строки с датами сравниваются напрямую, без перевода в метку времени. Формат даты сайта для такого прямого сравнения строк не годится.
Фильтр «не равно» пропускает элементы.
У части элементов этого значения нет вовсе, а вовсе не записан ноль. Отсутствующее значение в такое условие отбора попросту не попадает.
Частые вопросы
Как хранить дату со временем?
Типом «дата со временем»: он хранит и время тоже. Обычная дата время не сохраняет и обрезает его при записи.
Чем текст отличается от текста с разметкой?
Признаком вида у значения. Он же решает, как значение выводить и как чистить перед показом.
Можно ли фильтровать по части строки?
Да, приставкой поиска по вхождению. На больших каталогах такой отбор дорог и требует указателя в базе.
Что делать с диапазоном цен в фильтре?
Брать цену из торгового каталога, а не из свойства. Цена в свойстве не участвует в расчётах и скидках.
Смежное
-
Свойства инфоблоков - оглавление подтемы
-
Свой тип свойства инфоблока: регистрация, форма, хранение - когда штатных типов не хватает
-
Свойства инфоблока: чтение, запись и фильтрация по значению - работа со свойствами целиком
-
Свойства-списки: значения, сортировка, значение по умолчанию - соседний тип значений
-
Выборки из инфоблоков: GetList, ORM и разделы - как устроены фильтры выборки
-
Инфоблоки - устройство хранилища целиком
-
Даты в коде: объект, часовой пояс, фильтр по периоду - те же даты вне инфоблоков
-
Вывод дат на витрине: падежи, форматы сайта, относительное время - как показать дату покупателю
-
Визуальный редактор: панель, сниппеты, чистка вставленного кода - тип содержимого у поля с разметкой