Поднимаем лимит кол-ва символов в html свойстве в Bitrix
Последние записи
Хостинг для сайта
Если выбираете хостинг под проект — советую Timeweb. Современная инфраструктура, широкий выбор тарифов от стартовых до VPS под нагрузку, отзывчивая техподдержка, которая отвечает по существу, а не отписками. Я сам держу на нём часть своих проектов и рекомендую клиентам.
Перейти Партнёрская ссылка. Для вас цена не меняется.Почему свойство HTML/Текст обрезает контент на 63 200 символах
Разработчики, которым приходится иметь дело с длинными HTML-описаниями в инфоблоках, рано или поздно упираются в потолок. Вставляешь в свойство типа «HTML/Текст» статью на 80 тысяч символов — сохраняется только половина. Без ошибки, без предупреждения, просто молча обрезается. Это не баг конкретного проекта и не особенность сервера, а жёстко зашитое ограничение в ядре Bitrix.
В файле /bitrix/modules/iblock/classes/general/prop_html.php для MySQL установлен лимит $limit = 63200. С одной стороны, это защита от «тяжёлых» страниц и от раздувания базы. С другой — для проектов, где в одном свойстве хранится полноценная статья, спецификация или техническое описание, этого катастрофически мало. Ниже — три шага, которые снимают ограничение. И честное предупреждение о том, почему третий шаг — компромисс.
Шаг 1. Поднять pcre.backtrack_limit
Прежде чем трогать базу и ядро, нужно убедиться, что PCRE вообще способен обработать длинный текст. Директива pcre.backtrack_limit задаёт максимальное количество шагов отката для регулярных выражений. Если текст длинный, а сложный preg_match или preg_replace упирается в лимит, вы получите PREG_BACKTRACK_LIMIT_ERROR — и текст не сохранится вовсе, даже если все остальные лимиты подняты.
Правка делается в php.ini:
pcre.backtrack_limit = 20000000
Значение 20000000 (20 миллионов) — разумный потолок для большинства проектов. Оно с запасом покрывает и разбор HTML-контента, и работу с регулярными выражениями при сохранении. Если править php.ini нельзя, директиву можно задать через .htaccess или в init.php через ini_set('pcre.backtrack_limit', '20000000'). Второй вариант работает не на всех хостингах — зависит от того, разрешён ли ini_set для этой директивы.
Отдельно стоит понимать: pcre.backtrack_limit — это не про размер строки в базе, а про производительность регулярных выражений. Если после правки текст всё равно обрезается, дело не в PCRE, а в лимитах базы и ядра. Переходим к ним.
Шаг 2. Расширить тип столбца в базе
В Bitrix есть два режима хранения свойств инфоблока. Если инфоблок хранит свойства в отдельной таблице, значения лежат в b_iblock_element_prop_s{ID}, где {ID} — это ID инфоблока. Каждое свойство — отдельная колонка с именем вида PROPERTY_{ID}. Например, для свойства с PROPERTY_24 в инфоблоке с ID 4 таблица будет называться b_iblock_element_prop_s4, а колонка — PROPERTY_24.
По умолчанию под такие колонки Bitrix выделяет тип TEXT (или BLOB в зависимости от версии), который в MySQL ограничен 65 535 байтами. Для кириллицы в UTF-8 это примерно 32 тысячи символов, для латиницы — чуть больше 60 тысяч. Лимит 63200 в ядре как раз подогнан под этот потолок.
Сначала проверяем текущий тип колонки:
SHOW COLUMNS FROM b_iblock_element_prop_s4 WHERE Field = 'PROPERTY_24';
Убедившись, что там text или blob, меняем тип на MEDIUMTEXT или LONGTEXT. Первый даёт до 16 МБ, второй — до 4 ГБ. Для HTML-контента с запасом хватает MEDIUMTEXT, но если планируются совсем длинные тексты, лучше сразу LONGTEXT.
ALTER TABLE b_iblock_element_prop_s4
MODIFY COLUMN PROPERTY_24 LONGTEXT;
Для инфоблоков со старой схемой хранения, где свойства лежат в общей таблице b_iblock_element_property, запрос выглядит иначе — меняется колонка VALUE:
ALTER TABLE b_iblock_element_property
MODIFY COLUMN VALUE LONGTEXT;
Перед выполнением ALTER TABLE на production-сервере обязательно делаем резервную копию базы. На таблицах с миллионами строк операция может занять время и заблокировать запись. На staging-окружении проверяем, что данные не потерялись и приложение продолжает работать.
Шаг 3. Поднять порог в ядре
После расширения столбца текст всё равно обрежется на 63 200 символах, потому что лимит зашит в PHP-коде. Файл /bitrix/modules/iblock/classes/general/prop_html.php содержит строку:
if ($DB->type === "MYSQL")
$limit = 63200;
Меняем 63200 на нужное значение. Главное, чтобы он не превышал реальную вместимость столбца. Например:
if ($DB->type === "MYSQL")
$limit = 100000;
Размер текста в символах удобно проверять в Notepad++ или в консоли через wc -m. Кириллица в UTF-8 занимает два байта на символ, поэтому 100000 символов — это примерно 200000 байт, что с запасом влезает в MEDIUMTEXT.
Важное предупреждение. Правка ядра — это плохая практика. При первом же обновлении Bitrix файл prop_html.php будет перезаписан, и лимит вернётся к 63200. Если проект обновляется автоматически, вы даже не заметите, когда правка слетела — просто однажды контент снова начнёт обрезаться. Кроме того, правка ядра ломает поддержку: при обращении в техподдержку Bitrix первым делом попросят откатить изменения.
Альтернатива: собственный тип свойства с наследованием
Правильный путь — не трогать ядро, а сделать свой тип свойства инфоблока, унаследовавшись от стандартного HTML/Text и переопределив лимит. Bitrix поддерживает пользовательские свойства через событие OnIBlockPropertyBuildList. Класс-наследник регистрируется в init.php и живёт отдельно от ядра.
Ниже — минимальный пример. Он не претендует на продакшен-готовность, но показывает принцип: свой класс, свой лимит, никаких правок в /bitrix.
<?php
// /local/php_interface/init.php
class CustomHtmlProperty extends \CIBlockPropertyHTML
{
/**
* Переопределяет лимит длины для HTML-свойства.
*
* @return int
*/
public static function GetLength(): int
{
return 500000;
}
/**
* Описание пользовательского типа для системы.
*
* @return array
*/
public static function GetUserTypeDescription(): array
{
return [
'PROPERTY_TYPE' => 'S',
'USER_TYPE' => 'CUSTOM_HTML',
'DESCRIPTION' => 'HTML/Текст (расширенный)',
'GetLength' => [__CLASS__, 'GetLength'],
];
}
}
// Регистрируем обработчик
AddEventHandler('iblock', 'OnIBlockPropertyBuildList', ['CustomHtmlProperty', 'GetUserTypeDescription']);
После регистрации в настройках инфоблока появится новый тип свойства — «HTML/Текст (расширенный)». Он работает как стандартный, но не обрезает текст на 63200. Столбец в базе для него всё равно нужно расширить до LONGTEXT — это требование уровня хранилища, а не логики PHP.
Преимущества подхода:
- Обновления
Bitrixне затрагивают ваш класс. - Лимит можно менять в одном месте — в методе
GetLength(). - Если стандартное свойство нужно оставить с прежним лимитом, оба типа сосуществуют.
Единственный минус — существующие свойства типа «HTML/Текст» придётся перевести на новый тип вручную. На больших каталогах это делается скриптом или через миграцию.
Чек-лист
- Проверить, что
pcre.backtrack_limitвphp.iniне меньше20000000. - Определить, в какой таблице хранятся свойства:
b_iblock_element_prop_s{ID}илиb_iblock_element_property. - Выполнить
SHOW COLUMNSи убедиться, что колонка имеет типtextилиblob. - Сделать бэкап базы и выполнить
ALTER TABLE ... MODIFY ... LONGTEXT. - Зарегистрировать собственный тип свойства в
init.phpвместо правки ядра. - Перевести существующие свойства на новый тип или смириться с тем, что правка ядра слетит при обновлении.
Лимит в 63 200 символов — это не случайное число, а следствие старого лимита MySQL на тип TEXT. Технически снять его несложно, но делать это через правку ядра — значит закладывать мину на будущее. Собственный тип свойства с наследованием занимает чуть больше времени на старте, зато не ломается при обновлениях и не требует лезть в /bitrix.
Комментарии