Предисловие. Все, кто пользуются Битриксом, знают, до чего сложно порой бывает полностью настроить свой сайт так, как нужно. Одна часть настроек делается в административной части, другая часть в компонентах в публичной части. Тут не было бы проблем, если бы это были совершенно разные настройки, но они могут пересекаться. Самый яркий пример, с которым постоянно сталкиваются разработчики и покупатели интернет-магазинов, — необходимость настраивать адрес детальной страницы товара и в инфоблоке, и в компоненте каталога. Далее возникает необходимость указывать одни и те же параметры в нескольких компонентах на вашем сайте. Путь к странице с корзиной и путь к странице с оформлением заказа нужно задавать в компонентах большой и малой корзины, в компонентах каталога. Настройки инфоблока с товарами, правила добавления в корзину, покупку с характеристикой, свойства для отбора торговых предложений и многие другие настройки нужно задавать отдельно для различных компонентов каталога. Комплексный компонент bitrix:catalog частично избавляет от этой необходимости, но часть компонентов может быть размещена на отдельных страницах (блок спецпредложений на главной странице, дополнительный блок с товарами в разделе новостей и т.п.) и требует дополнительной идентичной настройки. С точки зрения самих компонентов это совершенно нормально, так как каждый из них должен быть полностью самостоятельным, независимым и работоспособным при размещении на любой странице сайта. Также это позволяет добиться универсальности: на разных страницах одни и те же компоненты можно настроить по-разному, например, выводить товары из разных каталогов с разными настройками. Но в рамках большого цельного сайта и особенно типовых решений такой подход к настройкам добавляет головной боли. Вам приходится постоянно помнить, в каких местах находятся одни и те же настройки, чтобы при необходимости их изменения ни о чем не забыть. А если вы купили и установили типовое решение, то о наличии некоторых страниц и/или настроек в компонентах поначалу можно даже и не подозревать. Будучи разработчиками типовых решений мы можем упростить и облегчить процесс настройки сайта и всех его компонентов в публичной части. Именно об этом пойдет в речь в этой статье.
Часть 1. Всё вертится вокруг каталога. Жизнь каждого интернет-магазина начинается с формирования и настройки каталога. После установки 1С-Битрикс и понравившегося шаблона интернет-магазина нам нужно выгрузить товары на сайт и отобразить их в каталоге. Каталог — это ядро нашего магазина, поэтому все настройки в первую очередь вносятся в комплексный компонент bitrix:catalog. И только после этого, имея основной каталог в качестве эталона, мы начинаем настраивать остальные компоненты аналогичным образом. И чем больше настроек нужно сделать для отображения товаров, тем больше их придется дублировать.
Рассмотрим следующий пример: в дизайне и верстке предусмотрен вывод артикула товара на страницах каталога в собственной области отдельно от всех остальных характеристик товара. Для реализации такой возможности в каталог нужно добавить новый параметр, позволяющий выбрать, какое из свойств инфоблока должно выводиться отдельно в качестве артикула.
Далее возникает необходимость также выводить артикул товара в малой и большой корзине.Стандартный подход Битрикса подразумевает, что мы должны добавить аналогичные параметры в шаблоны малой и большой корзины. А это значит, что в итоге мы будем задавать один и тот же параметр в трех компонентах. А если захотим вывести артикул еще в каких-либо компонентах, то потом и там нужно будет настраивать отдельно. К тому же набор свойств для выбора берется из инфоблока, который выбран в параметрах компонента каталога. В компонентах корзины такого выбора нет, так как корзине не нужно указывать какой-то конкретный инфоблок для работы, она работает одинаково для любых инфоблоков, из которых добавляются товары. Чтобы задавать такие параметры в компонентах корзины, понадобится еще и самостоятельно делать дополнительную выборку этих свойств/инфоблоков. При таком подходе, даже настроив отображение артикула в каталоге, мы не сразу узнаем, что можем вывести артикул товара и в других компонентах.
Можно ли выполнить настройку как-то по другому? У нас уже есть параметры, заданные для всего каталога. Нам нужно лишь как-то их получить и использовать в других компонентах решения. Один из способов для достижения этой цели — записывать параметры компонента в кеш в шаблоне каталога, а потом читать их из кеша в шаблонах всех остальных компонентов, где понадобится обработка и вывод какой-либо информации по аналогии с каталогом. Давайте рассмотрим по шагам, как реализуется такой механизм.
$ob = new \CPHPCache();
if ($ob->InitCache($_cacheTime, $_cacheId, $_cachePath, $_cacheDir)) {
// if cache is valid check params equality
if ($arParams != $ob->GetVars()) {
// if not - clean cache
$ob->Clean($_cacheId, $_cachePath, $_cacheDir);
}
}
// write down params if there is no cache
if ($ob->StartDataCache($_cacheTime, $_cacheId, $_cachePath, array(), $_cacheDir)) {
$ob->EndDataCache($arParams);
}
unset($ob);
В result_modifier.php шаблона комплексного компонента bitrix:catalog проверяем наличие кеша с параметрами компонента.
Если он существует, сверяем с текущим набором параметров. При несовпадении удаляем кеш.
Записываем текущие параметры каталога в кеш с уникальным идентификатором.
В другом компоненте читаем параметры каталога из кеша с этим же уникальным идентификатором. Если кеш еще не создан, используем значения по умолчанию.
Пользуемся.
Можно подумать, что реализация такого механизма всего лишь для отображения какого-то артикула в корзине совершенно избыточна, ведь можно просто добавить артикул в корзину как свойство товара, а потом вывести его там. Но лучше не класть разные сущности в одну корзину, ведь может понадобиться и обычный функционал покупки с характеристикой, и тогда в заказах в админке будет каша из купленных свойств товара вперемешку со служебными. А еще больше радует использование такого подхода, когда нужно в корзине вывести наличие товара на отдельных складах, а этот блок задается сразу несколькими параметрами в компоненте каталога и уж точно никак не может существовать в виде свойств товара в корзине.
При хранении параметров в кеше необходимо учитывать две особенности.
Кеш имеет свойство удаляться различными способами. Наш кеш с параметрами чистить нет смысла, он и так будет автоматически обновляться при изменении параметров компонента. А вот если в тот небольшой промежуток, пока нового кеша каталога нет, кто-то откроет другую страницу с компонентом, использующим этот кеш, то он получит не совсем тот вид страницы, как обычно.
Для того, чтобы этот кеш не удалялся даже при сбросе всего кеша в административной части сайта, необходимо разместить его в другой базовой директории. Базовая директория задается третьим аргументом метода CPHPCache::Clean(), четвертым аргументом метода CPHPCache::InitCache() и пятым аргументом метода CPHPCache::StartDataCache(). По умолчанию значение этих аргументов "cache", поэтому весь кеш хранится в директории /bitrix/cache.
В своем решении для хранения этого кеша мы указываем базовую директорию "cache_romza", и кеш параметров каталога попадает в папку /bitrix/cache_romza, и как следствие не удаляется при очистке всего кеша сайта в административной части.
Никакие данные нельзя прочитать из кеша, если на странице была выполнена команда "Сбросить кеш" в административной панели (?clear_cache=Y), или если пользователь отключил кеширование для всего сеанса (?clear_cache_session=Y).
Есть способ обойти и это затруднение. Перед чтением параметров из кеша необходимо отключить режим работы без кеша, а после чтения параметров включить его обратно, если он был активен.
// =========== TURN OFF CLEAR_CACHE ===========
$clearCache = Bitrix\Main\Data\Cache::setClearCache(false);
$clearCacheSession = (isset($_SESSION["SESS_CLEAR_CACHE"]) && $_SESSION["SESS_CLEAR_CACHE"] === "Y");
Bitrix\Main\Data\Cache::setClearCacheSession(false);
if ($clearCacheSession) unset($_SESSION["SESS_CLEAR_CACHE"]);
// ============================================
… Читаем параметры из кеша …
// ============ TURN ON CLEAR_CACHE BACK IF NEEDED ===============
if ($clearCache) Bitrix\Main\Data\Cache::setClearCache(true);
if ($clearCacheSession) {
Bitrix\Main\Data\Cache::setClearCacheSession(true);
$_SESSION["SESS_CLEAR_CACHE"] = "Y";
}
// ===============================================================
Есть и другой подход, при котором с помощью стандартных классов Битрикса можно парсить файл /catalog/index.php и выдирать нужные параметры прямо оттуда. Но в этом случае нужно быть однозначно уверенным, что вызов компонента каталога находится именно поэтому адресу. Такой подход может быть использован только в частной разработке под конкретного клиента. При разработке типового решения мы не можем быть уверены, что конечный клиент не захочет переименовать папку с каталогом в /c/index.php или еще как-нибудь. Способ с записью параметров в кеш из шаблона компонента позволяет абстрагироваться от места вызова компонента. Вдобавок мы получаем нормально сформированный массив параметров, который прошел через предварительную обработку компонентом и наши собственные манипуляции с параметрами в result_modifier.php до момента записи в кеш. Если какие-либо параметры каталога зависят от переменных, которые могут регулярно изменяться, то их лучше изменять после проверки и записи в кеш. Этот же кеш с параметрами можно использовать для подгрузки частей каталога через AJAX, чтобы не гонять параметры в открытом или зашифрованном виде от сервера клиенту и от клиента обратно на сервер.
Часть 2. Панель настройки сайта. Еще один подход к быстрой и простой настройке сайта состоит в том, чтобы создать отдельную панель для единой настройки всех визуальных составляющих. В первую очередь это касается параметров отображения шаблона сайта, то есть того, что не относится ни к одному из компонентов (фон страницы, расположение блоков в шапке и т.п.).
Но также можно вынести ряд одинаковых параметров из разных компонентов в панель для удобства настройки, если они не требуют выборки дополнительных данных на основе других параметров компонента. Такие параметры можно было бы организовать в виде настроек модуля в административной части сайта, но их расположение в публичке позволяет быстрее увидеть результат или даже мгновенно у тех параметров, которые поддерживают "живое" переключение с помощью JS; автоматически определять и разделять настройки для разных сайтов в многосайтовой конфигурации; давать возможность индивидуальной настройки для разных пользователей. Хранение таких настроек тоже весьма интересная задача.
Изначально компонент панели настроек записывал настройки авторизованных пользователей и настройки по умолчанию для всех в COption — по одной записи на каждый параметр, а настройки для неавторизованных пользователей сохранялись в куки — по одной куки на каждый параметр. Такой подход неплохо справлялся со своей задачей, пока количество параметров в панели настроек во всех наших прошлых типовых решениях было небольшим. В типовом решении Битроник 2 общее количество параметров в панели настроек достигло порядка 150. Привело это к тому, что в таблице b_option на демо-сайте решения накопилось свыше 3500 записей c настройками посетителей. Но еще хуже тот факт, что далеко не все браузеры могут сохранить такое количество кук. В браузерах IE и Edge от Microsoft даже последних версий позволяется хранить только 50 кук с одного сайта. Из-за этого настройки решения у неавторизованных пользователей в этих браузерах не сохранялись в принципе. Да и в других браузерах куки начинали периодически пропадать. Для того, чтобы избежать всех этих проблем, решено было также сохранять массив параметров в изолированный кеш с теми же двумя мерами защиты от сброса, как и в первой части статьи. В качестве ID кеша используется хеш массива, который уже записывается в COption или в куку для каждого отдельного пользователя. Таким образом, мы теперь делаем не по 150 записей на каждого пользователя, а всего по одной с ключем от кеша с массивом параметров. Общие настройки сайта, установленные администратором, помимо кеша по-прежнему дублируются отдельными записями в COption для лучшей стабильности работы.
Послесловие. В этой статье был рассмотрен способ хранения каких-либо параметров в изолированном кеше с защитой от сброса для его распределенного использования на вашем сайте и два примера использования такого подхода для получения параметров комплексного компонента каталога в других компонентах и скриптах, а также хранения огромного массива настроек типового решения. Надеемся, что эта информация была интересной и полезной. Будем рады услышать любую конструктивную критику и обсудить другие возможные альтернативные способы решения проблем, затронутых в этой статье.
ОБНОВЛЕНИЕ. Ответы на вопросы из комментариев.
Задойный Алексей написал: Я к тому, что насмерть кешировать что-то - это очень опасная затея, если всё хорошенько не обдумать. И есть риск, что такое мощное оружие попадёт не в те руки.Безусловно. Любое оружие накладывает ответственность за его использование. А испортить можно что угодно и чем угодно, если не включать голову. Чего нам нужно бояться при вечном кешировании, которое нельзя очистить стандартными инструментами?
Бесконечное размножение файлов с кешем и заполнение всего доступного дискового пространства. В первом примере это кеш с параметрами одного компонента. По сути сериализованная копия файла /catalog/index.php (по умолчанию) для чтения в любом другом скрипте независимо от того, по какому пути расположен наш файл с вызовом комплексного каталога. То есть независимо от настроек каталога, независимо от пользователя это всегда только один файл. Изменили настройки каталога в режиме правки, изменилось содержимое нашего файла с кешем настроек. Если понадобится хранить настройки еще одного компонента таким образом, появится еще один файл. По одному файлу на один компонент, чьи настройки нужно хранить. Таким образом за переполнение диска в этом случае волноваться не стоит. Во втором примере уже посложнее, так как на каждую комбинацию настроек создается отдельный файл с кешем. Но тут мы опираемся на многочисленные примеры реального использования клиентами панели настроек. Изначально после установки решения панель настроек закрыта от всех пользователей, кроме администраторов. Администратор настраивает один раз, как сайт должен выглядеть для его посетителей, и может еще отдельно задать настройки лично для себя. На этом всё и заканчивается. Никто не открывает к панели настроек доступ для посетителей, чтобы они могли менять внешний вид под себя. Реально такой функционал используется только на демо-сайте решения, чтобы любой человек мог изучить возможности панели настроек без получения администраторских прав доступа. Но тут несложно написать агент, который будет удалять те файлы кеша, которые не принадлежат авторизованным пользователям и были созданы давно.
Невозможность обновить вид страниц стандартным сбросом кеша. Такая проблема может возникнуть при кешировании $arResult или конечного HTML. Но мы записываем в кеш не конечный результат, а исходный набор параметров компонента, от которого уже зависит всё остальное. И этот набор параметров является актуальной копией того, что мы имеем в файле /catalog/index.php за счет постоянной синхронизации. Так что об этом тоже можно не беспокоиться.
Если существуют еще проблемы, которые возникают при несбрасываемом кеше, прошу их перечислить, чтобы можно было также обсудить.
==========================================
Забродин Роман написал: Возникает вопрос, а если пользователь начинает просмотр сайта не со страницы где расположен комплексный компонент каталога, а с какой-то другой, как тогда получить параметры, ведь получается что кэш с ними еще не создан?
Если быть точнее, то и не вопрос возникает, а серьезная проблема. На протяжении нескольких лет мы записываем параметры каталога в кеш для обновления самого каталога через AJAX, а во втором Битронике мы уже начали использовать его и в других компонентах тоже. Но даже при использовании только для AJAX регулярно происходили ситуации, когда мы загрузили в браузер страницу, в этот момент кеш сбросился по какой-либо причине, и никакие AJAX-запросы на нашей странице работать не будут: мы не сможем положить товар в корзину, перейти на другую страницу раздела, поменять сортировку, отфильтровать товары и т.д., пока не перезагрузим страницу, или пока кто-то другой не откроет страницу этого же каталога, создав кеш заново.
Таким образом, вышеобозначенная ситуация, что мы открываем какую-то страницу без комплексного компонента каталога, но на ней используются настройки этого компонента (берутся из кеша), возникает ВСЕГО ОДИН РАЗ. В тот момент, когда мы только что развернули типовое решение с помощью мастера установки. На последнем шаге мастера находится кнопка "Перейти на сайт". Мы нажимаем её и попадаем на главную страницу. Вот она загрузилась, но кеша с параметрами каталога еще нет. Что нам нужно делать в этом случае? Да ничего не нужно делать, так как каталог еще никто не настраивал, и в нем сейчас стандартные настройки, которые лежат в нашем дистрибутиве. Поэтому, не получив из кеша массив с настройками, мы смело используем параметры по умолчанию. Как долго не будет кеша с параметрами каталога? До первого захода на любую страницу каталога. Что произойдет моментально, так как после установки мы сразу идем и проверяем, всё ли работает. И вот мы открыли любую страницу каталога, наш кеш создан, ВСЁ. Он един для всех пользователей, так же как едины и параметры каталога. С этого момента для любого посетителя при посещении любой страницы сайта этот кеш будет существовать. Если мы зашли и поменяли настройки каталога, они сразу же поменялись и в нашем кеше.
Исключения:
Настройки каталога изменили руками в PHP-коде файла с вызовом компонента. Этот момент мы никак не можем отследить, но такое во-первых делается нечасто, а во-вторых настройки в кеше обновятся сразу же после загрузки любой страницы каталога. Вы же не меняете параметры руками в PHP-коде просто так от нечего делать каждый день по 100 раз? Такое делается очень редко и явно не просто так. После смены параметров через код, мы в любом случае обновим страницу, чтобы проверить, был ли достигнут желаемый результат. И, как следствие, кеш с настройками опять обновился.
Файлы кеша были удалены вручную из папки. Еще более вырожденный случай. Не каждый рядовой администратор сайта будет ходить по жесткому диску с метлой и удалять все файлы без разбора. А от стандартной очистки кеша мы защитились размещением в отдельной директории. НО! Даже в этом случае чтение параметров из кеша производится не просто так в каждом шаблоне по отдельности. Для этого создан специальный метод в нашем ядре (yenisite.core), который делает следующее: - проверяем наличие кеша с нужными параметрами, - если кеш отсутствует, делаем однократный запрос через HttpClient на страницу компонента с двумя специальными параметрами в URL, чтобы не выполнялась шапка сайта и не рендерился шаблон компонента и всё, что после него — только сохранение параметров в кеш и возвращение сообщения об успехе. Страница компонента передается через аргумент метода. По умолчанию "/catalog/index.php", где и расположен файл после установки. На большинстве сайтов путь к каталогу не меняется. И это значит, что… кеш будет доступен всегда. - Даже если это самый первый хит на сайт сразу после установки. - Даже если какой-то злодей руками стер кеш с параметрами компонента. А для случая, когда компонент каталога переносится в другую директорию, можно доработать конструкцию до еще большей стабильности: добавить возможность указывать директорию к каталогу в настройках модуля. И это может быть полезно не только для такого исключительно редкого случая, но и для того, чтобы избежать ряда других проблем. В некоторых типовых решениях приходится кастомизировать шаблон сайта для корректной работы, если компонент каталога размещен в другой директории. Еще несколько нюансов касательно ручного удаления файлов кеша с диска будут в ответе на последующие вопросы.
Забродин Роман написал: И еще вопрос, почему они записываются именно в кэш, а не например в таблицу БД b_option?
Для ответа на этот вопрос обратимся к документации.
Максимальная сохраняемая длина значения - 2000 символов.
Если открыть дистрибутив решения и посчитать количество символов в массиве с параметрами компонента каталога, то их окажется больше 6000. В сериализованном виде массив занимает еще чуть больше. - Имеются ли такие ограничения у файлового кеша? - Нет.
- Можно ли хранить каждый параметр каталога в отдельном COption? - Можно, но зачем? Во-первых, их будет дофига. Во-вторых, получить все настройки каталога одной строчкой кода не получится, API Битрикса предоставляет возможность получать только один COption с помощью одного вызова GetOptionInt() или GetOptionString(). Значит нужно писать свой метод, который будет или дергать их по очереди один за другим и записывать в массив (а для этого еще нужно знать имя каждого параметра, и потом постоянно дублировать при добавлении новых параметров), или делать запрос напрямую в БД, чтобы самостоятельно выбрать все нужные записи. В любом случае это громоздко и жутко. В-третьих, читаем комментарий Антона Долганина:
Категорически не рекомендуется использовать данный метод для хранения объемной информации (максимум - обычные переменные, фразы, маленькие массивы). Дело в том, что все значения переменных, всех модулей наполняют массив GLOBALS на каждом хите.
Злоупотребление данным методом может сказаться в конечном счете на производительности всей системы.
Комментарий датируется 2013 годом. К счастью, сейчас дело обстоит уже не совсем так, но тем не менее при попытке чтения хотя бы одного COption в память загружаются все COption модуля для текущего сайта. Поэтому COption всё равно не стоит злоупотреблять. И мне даже страшно думать о том, что творилось на нашем демо-сайте всё это время, пока на каждом хите в память загружались почти 4000 записей настроек ВСЕХ пользователей для панели настроек.
Забродин Роман написал: Знаю, что многие разработчики, уже воспринимают директорию /cache/ как хранилище всяческого "мусора", которую можно чистить как "корзину" прямо удаляя все ее содержимое (F8 в FAR ) не станет ли для них описанный механизм хранения параметров неприятным сюрпризом?
1) В том числе и поэтому мы не записываем теперь этот кеш в папку /cache/, а записываем в папку /cache_romza/. 2) Если действительно многие разработчики накидываются с клавишей Delete на любую папку, в названии которой содержится слово "cache" в любом виде, тогда возможно стоит переименовать папку в /romza_settings/ или /romza/settings/, или любое другое название, которое не будет вызывать у прожженых разработчиков позывов отправить содержимое каталога в корзину, и вообще к нему прикасаться.
Здесь важно понять, что по своей сути это вообще не кеш. Это хранилище настроек, для реализации которого почти идеально подходит иеющийся в Битриксе класс CPHPCache.
Забродин Роман написал: Так все таки в куку или в COption? Потому, что если в куку, то авторизовавшись на сайте в другом браузере или с другого компьютера (где нет той куки) пользователь получается, что не получит своих настроек?
Как работала панель настроек раньше? Все настройки неавторизованных пользователей записывались в виде отдельных куки в браузер. Все настройки авторизованных пользователей записывались в COption отдельными записями, чтобы могли применяться при авторизации с любого устройства. Это было указано в статье.
Как работает панель настроек сейчас? Все настройки неавторизованных пользователей записываются в кеш. Ключ от кеша записывается в браузер одной кукой. Все настройки авторизованных пользователей записываются в кеш. Ключ от кеша записывается в COption одной записью. Ключ от кеша сохраняется в куки или COption по такому же принципу, как и раньше. Без авторизации настройки не сохраняются при переходе на другое устройство. Авторизованный пользователь получает свои настройки при заходе с любого устройства.
Забродин Роман написал: А в каком конкретно файле компонентов происходит чтение этих параметров? На сколько я понимаю, исполнение этого файла никогда не должно кэшироваться?
В данный момент в Битронике 2 такое чтение параметров используется в шаблонах малой и большой корзин, которые никогда не кешируются, а также в шаблоне комплексного компонента новостей, который тоже не кешируется. Да, всё верно. Получается, что чтение кеша должно быть в некешируемой части. Пока что еще не было необходимости заниматься этим в кешируемых областях. Но даже в этом случае можно накинуть сверху тегирование кеша, чтобы это не было проблемой. Чуть больше труда разработчика = значительно легче жизнь администратора сайта.
Микулич Евгений написал: Ещё никогда я не был так согласен с Забродиным Романом.
А наш отдел разработки не согласен
По каждому из вопросов и замечаний был дан ответ. Надеюсь, что они были достаточно подробны и понятны.
Как всегда с нетерпением ждем следующей порции конструктивной критики, чтобы постараться развеять ваши сомнения, либо обнаружить что-то еще, что мы могли упустить из виду, и пролить в конечном счете свет на истину.
Наверное надо какой-то дисклеймер вешать (или выскакивающий баннер каждые 30 секунд) из серии "лицам старше 18 лет". Я к тому, что насмерть кешировать что-то - это очень опасная затея, если всё хорошенько не обдумать. И есть риск, что такое мощное оружие попадёт не в те руки. Просто я пару раз сталкивался с сайтом на котором кнопка сборса кеша ни к чему не приводила. Знаете, в такие мгновения меня одолевает паника. Это даже хуже, чем когда видишь 100500 запросов к БД, которые не кешируются (и вообще кеш каталога стоит в положении N, "потому что иначе вёрстка едет"). Тогда-то ясно что делать.
А вообще подход очень интересный. Уже насколько привык к этому разнообразию мест для настроек, что почти привык... А ведь можно наверное и по-человечески... 8)
Фалеев Илья написал: Один из способов для достижения этой цели — записывать параметры компонента в кеш в шаблоне каталога, а потом читать их из кеша в шаблонах всех остальных компонентов, где понадобится обработка и вывод какой-либо информации по аналогии с каталогом.
Возникает вопрос, а если пользователь начинает просмотр сайта не со страницы где расположен комплексный компонент каталога, а с какой-то другой, как тогда получить параметры, ведь получается что кэш с ними еще не создан?
И еще вопрос, почему они записываются именно в кэш, а не например в таблицу БД b_option?
В своем решении для хранения этого кеша мы указываем базовую директорию "cache_romza", и кеш параметров каталога попадает в папку /bitrix/cache_romza, и как следствие не удаляется при очистке всего кеша сайта в административной части.
Знаю, что многие разработчики, уже воспринимают директорию /cache/ как хранилище всяческого "мусора", которую можно чистить как "корзину" прямо удаляя все ее содержимое (F8 в FAR ) не станет ли для них описанный механизм хранения параметров неприятным сюрпризом?
В качестве ID кеша используется хеш массива, который уже записывается в COption или в куку для каждого отдельного пользователя.
Так все таки в куку или в COption? Потому, что если в куку, то авторизовавшись на сайте в другом браузере или с другого компьютера (где нет той куки) пользователь получается, что не получит своих настроек?
Задойный Алексей написал: Я к тому, что насмерть кешировать что-то - это очень опасная затея, если всё хорошенько не обдумать. И есть риск, что такое мощное оружие попадёт не в те руки.
Безусловно. Любое оружие накладывает ответственность за его использование. А испортить можно что угодно и чем угодно, если не включать голову. Чего нам нужно бояться при вечном кешировании, которое нельзя очистить стандартными инструментами?
Бесконечное размножение файлов с кешем и заполнение всего доступного дискового пространства. В первом примере это кеш с параметрами одного компонента. По сути сериализованная копия файла /catalog/index.php (по умолчанию) для чтения в любом другом скрипте независимо от того, по какому пути расположен наш файл с вызовом комплексного каталога. То есть независимо от настроек каталога, независимо от пользователя это всегда только один файл. Изменили настройки каталога в режиме правки, изменилось содержимое нашего файла с кешем настроек. Если понадобится хранить настройки еще одного компонента таким образом, появится еще один файл. По одному файлу на один компонент, чьи настройки нужно хранить. Таким образом за переполнение диска в этом случае волноваться не стоит. Во втором примере уже посложнее, так как на каждую комбинацию настроек создается отдельный файл с кешем. Но тут мы опираемся на многочисленные примеры реального использования клиентами панели настроек. Изначально после установки решения панель настроек закрыта от всех пользователей, кроме администраторов. Администратор настраивает один раз, как сайт должен выглядеть для его посетителей, и может еще отдельно задать настройки лично для себя. На этом всё и заканчивается. Никто не открывает к панели настроек доступ для посетителей, чтобы они могли менять внешний вид под себя. Реально такой функционал используется только на демо-сайте решения, чтобы любой человек мог изучить возможности панели настроек без получения администраторских прав доступа. Но тут несложно написать агент, который будет удалять те файлы кеша, которые не принадлежат авторизованным пользователям и были созданы давно.
Невозможность обновить вид страниц стандартным сбросом кеша. Такая проблема может возникнуть при кешировании $arResult или конечного HTML. Но мы записываем в кеш не конечный результат, а исходный набор параметров компонента, от которого уже зависит всё остальное. И этот набор параметров является актуальной копией того, что мы имеем в файле /catalog/index.php за счет постоянной синхронизации. Так что об этом тоже можно не беспокоиться.
Если существуют еще проблемы, которые возникают при несбрасываемом кеше, прошу их перечислить, чтобы можно было также обсудить.
==========================================
Забродин Роман написал: Возникает вопрос, а если пользователь начинает просмотр сайта не со страницы где расположен комплексный компонент каталога, а с какой-то другой, как тогда получить параметры, ведь получается что кэш с ними еще не создан?
Если быть точнее, то и не вопрос возникает, а серьезная проблема. На протяжении нескольких лет мы записываем параметры каталога в кеш для обновления самого каталога через AJAX, а во втором Битронике мы уже начали использовать его и в других компонентах тоже. Но даже при использовании только для AJAX регулярно происходили ситуации, когда мы загрузили в браузер страницу, в этот момент кеш сбросился по какой-либо причине, и никакие AJAX-запросы на нашей странице работать не будут: мы не сможем положить товар в корзину, перейти на другую страницу раздела, поменять сортировку, отфильтровать товары и т.д., пока не перезагрузим страницу, или пока кто-то другой не откроет страницу этого же каталога, создав кеш заново. Эта проблема была решена перемещением кеша с параметрами из стандартной папки /bitrix/cache/ в отдельную директорию /bitrix/cache_romza/, чтобы он не удалялся стандартными средствами Битрикса. (Еще была проблема в том, что в Битронике использовался компонент, который в принципе регулярно грохал всю папку /bitrix/cache/, но это уже отдельный разговор).
Таким образом, вышеобозначенная ситуация, что мы открываем какую-то страницу без комплексного компонента каталога, но на ней используются настройки этого компонента (берутся из кеша), возникает ВСЕГО ОДИН РАЗ. В тот момент, когда мы только что развернули типовое решение с помощью мастера установки. На последнем шаге мастера находится кнопка "Перейти на сайт". Мы нажимаем её и попадаем на главную страницу. Вот она загрузилась, но кеша с параметрами каталога еще нет. Что нам нужно делать в этом случае? Да ничего не нужно делать, так как каталог еще никто не настраивал, и в нем сейчас стандартные настройки, которые лежат в нашем дистрибутиве. Поэтому, не получив из кеша массив с настройками, мы смело используем параметры по умолчанию. Как долго не будет кеша с параметрами каталога? До первого захода на любую страницу каталога. Что произойдет моментально, так как после установки мы сразу идем и проверяем, всё ли работает. И вот мы открыли любую страницу каталога, наш кеш создан, ВСЁ. Он един для всех пользователей, так же как едины и параметры каталога. С этого момента для любого посетителя при посещении любой страницы сайта этот кеш будет существовать. Если мы зашли и поменяли настройки каталога, они сразу же поменялись и в нашем кеше.
Исключения:
Настройки каталога изменили руками в PHP-коде файла с вызовом компонента. Этот момент мы никак не можем отследить, но такое во-первых делается нечасто, а во-вторых настройки в кеше обновятся сразу же после загрузки любой страницы каталога. Вы же не меняете параметры руками в PHP-коде просто так от нечего делать каждый день по 100 раз? Такое делается очень редко и явно не просто так. После смены параметров через код, мы в любом случае обновим страницу, чтобы проверить, был ли достигнут желаемый результат. И, как следствие, кеш с настройками опять обновился.
Файлы кеша были удалены вручную из папки. Еще более вырожденный случай. Не каждый рядовой администратор сайта будет ходить по жесткому диску с метлой и удалять все файлы без разбора. А от стандартной очистки кеша мы защитились размещением в отдельной директории. НО! Даже в этом случае чтение параметров из кеша производится не просто так в каждом шаблоне по отдельности. Для этого создан специальный метод в нашем ядре (yenisite.core), который делает следующее: - проверяем наличие кеша с нужными параметрами, - если кеш отсутствует, делаем однократный запрос через HttpClient на страницу компонента с двумя специальными параметрами в URL, чтобы не выполнялась шапка сайта и не рендерился шаблон компонента и всё, что после него — только сохранение параметров в кеш и возвращение сообщения об успехе. Страница компонента передается через аргумент метода. По умолчанию "/catalog/index.php", где и расположен файл после установки. На большинстве сайтов путь к каталогу не меняется. И это значит, что… кеш будет доступен всегда. - Даже если это самый первый хит на сайт сразу после установки. - Даже если какой-то злодей руками стер кеш с параметрами компонента. А для случая, когда компонент каталога переносится в другую директорию, можно доработать конструкцию до еще большей стабильности: добавить возможность указывать директорию к каталогу в настройках модуля. И это может быть полезно не только для такого исключительно редкого случая, но и для того, чтобы избежать ряда других проблем. В некоторых типовых решениях приходится кастомизировать шаблон сайта для корректной работы, если компонент каталога размещен в другой директории. Еще несколько нюансов касательно ручного удаления файлов кеша с диска будут в ответе на последующие вопросы.
Забродин Роман написал: И еще вопрос, почему они записываются именно в кэш, а не например в таблицу БД b_option?
Для ответа на этот вопрос обратимся к документации.
Максимальная сохраняемая длина значения - 2000 символов.
Если открыть дистрибутив решения и посчитать количество символов в массиве с параметрами компонента каталога, то их окажется больше 6000. В сериализованном виде массив занимает еще чуть больше. - Имеются ли такие ограничения у файлового кеша? - Нет.
- Можно ли хранить каждый параметр каталога в отдельном COption? - Можно, но зачем? Во-первых, их будет дофига. Во-вторых, получить все настройки каталога одной строчкой кода не получится, API Битрикса предоставляет возможность получать только один COption с помощью одного вызова GetOptionInt() или GetOptionString(). Значит нужно писать свой метод, который будет или дергать их по очереди один за другим и записывать в массив (а для этого еще нужно знать имя каждого параметра, и потом постоянно дублировать при добавлении новых параметров), или делать запрос напрямую в БД, чтобы самостоятельно выбрать все нужные записи. В любом случае это громоздко и жутко. В-третьих, читаем комментарий Антона Долганина:
Категорически не рекомендуется использовать данный метод для хранения объемной информации (максимум - обычные переменные, фразы, маленькие массивы). Дело в том, что все значения переменных, всех модулей наполняют массив GLOBALS на каждом хите.
Злоупотребление данным методом может сказаться в конечном счете на производительности всей системы.
Комментарий датируется 2013 годом. К счастью, сейчас дело обстоит уже не совсем так, но тем не менее при попытке чтения хотя бы одного COption в память загружаются все COption модуля для текущего сайта. Поэтому COption всё равно не стоит злоупотреблять. И мне даже страшно думать о том, что творилось на нашем демо-сайте всё это время, пока на каждом хите в память загружались почти 4000 записей настроек ВСЕХ пользователей для панели настроек.
Забродин Роман написал: Знаю, что многие разработчики, уже воспринимают директорию /cache/ как хранилище всяческого "мусора", которую можно чистить как "корзину" прямо удаляя все ее содержимое (F8 в FAR ) не станет ли для них описанный механизм хранения параметров неприятным сюрпризом?
1) В том числе и поэтому мы не записываем теперь этот кеш в папку /cache/, а записываем в папку /cache_romza/. 2) Если действительно многие разработчики накидываются с клавишей Delete на любую папку, в названии которой содержится слово "cache" в любом виде, тогда возможно стоит переименовать папку в /romza_settings/ или /romza/settings/, или любое другое название, которое не будет вызывать у прожженых разработчиков позывов отправить содержимое каталога в корзину, и вообще к нему прикасаться.
Здесь важно понять, что по своей сути это вообще не кеш. Это хранилище настроек, для реализации которого почти идеально подходит иеющийся в Битриксе класс CPHPCache.
Забродин Роман написал: Так все таки в куку или в COption? Потому, что если в куку, то авторизовавшись на сайте в другом браузере или с другого компьютера (где нет той куки) пользователь получается, что не получит своих настроек?
Как работала панель настроек раньше? Все настройки неавторизованных пользователей записывались в виде отдельных куки в браузер. Все настройки авторизованных пользователей записывались в COption отдельными записями, чтобы могли применяться при авторизации с любого устройства. Это было указано в статье.
Как работает панель настроек сейчас? Все настройки неавторизованных пользователей записываются в кеш. Ключ от кеша записывается в браузер одной кукой. Все настройки авторизованных пользователей записываются в кеш. Ключ от кеша записывается в COption одной записью. Ключ от кеша сохраняется в куки или COption по такому же принципу, как и раньше. Без авторизации настройки не сохраняются при переходе на другое устройство. Авторизованный пользователь получает свои настройки при заходе с любого устройства.
Забродин Роман написал: А в каком конкретно файле компонентов происходит чтение этих параметров? На сколько я понимаю, исполнение этого файла никогда не должно кэшироваться?
В данный момент в Битронике 2 такое чтение параметров используется в шаблонах малой и большой корзин, которые никогда не кешируются, а также в шаблоне комплексного компонента новостей, который тоже не кешируется. Да, всё верно. Получается, что чтение кеша должно быть в некешируемой части. Пока что еще не было необходимости заниматься этим в кешируемых областях. Но даже в этом случае можно накинуть сверху тегирование кеша, чтобы это не было проблемой. Чуть больше труда разработчика = значительно легче жизнь администратора сайта.
Микулич Евгений написал: Ещё никогда я не был так согласен с Забродиным Романом.
А наш отдел разработки не согласен
По каждому из вопросов и замечаний был дан ответ. Надеюсь, что они были достаточно подробны и понятны.
Как всегда с нетерпением ждем следующей порции конструктивной критики, чтобы постараться развеять ваши сомнения, либо обнаружить что-то еще, что мы могли упустить из виду, и пролить в конечном счете свет на истину.
Фалеев Илья написал: Если существуют еще проблемы, которые возникают при несбрасываемом кеше, прошу их перечислить, чтобы можно было также обсудить.
Самая существенная проблема в том, что на материал могут взять на вооружение люди для вечного кеширования чего угодно, а не только того, что описали вы. Я же не говорю, что вы что-то сделали неправильно.
Настройки каталога изменили руками в PHP-коде файла с вызовом компонента.Этот момент мы никак не можем отследить, но такое во-первых делается нечасто, а во-вторых настройки в кеше обновятся сразу же после загрузки любой страницы каталога.
А вот это уже плохо. Во-первых предупреждать надо. Во-вторых, я например, меняю как раз руками. И в случае работы с вашим решением был бы весьма удивлён его "странным поведением" вероятно. Т.е. это конечно не смертельно, это именно неприятно и непонятно. И неожиданно наверное. Хотя решение, как я написал выше очень интересное.
Кстати, разрастание папки с вашим кешом не происходит? А на больших проектах? А после их кастомизации партнёрами?
Задойный Алексей, Я вообще всё делаю в коде, а тут такая подстава будет? Для кого решение то:) Если для разработчика - то должен быть подход разработчика. С Вами тоже согласен.
Задойный Алексей написал: Во-первых предупреждать надо. Во-вторых, я например, меняю как раз руками. И в случае работы с вашим решением был бы весьма удивлён его "странным поведением" вероятно. Т.е. это конечно не смертельно, это именно неприятно и непонятно. И неожиданно наверное.
Эта статья как раз для "во-первых". Во-вторых, сценарий со сменой параметров комплексного каталога из кода, затем, например, открытия сразу большой корзины и ожидания что там что-то будет по-другому - маловероятен и не смертелен в данном случае. Естественно что надо вдумчиво подходить к таким вопросам.
Задойный Алексей написал: Кстати, разрастание папки с вашим кешом не происходит? А на больших проектах? А после их кастомизации партнёрами?
Как Илья написал выше - кеш хранится в 1 файле для одного компонента, так что разрастание не планируется. А если это к настройкам опций - то немного статистики - с 19 ноября было создано 681 файл настроек каждый примерно по 4.3Кб что около 3МБ, учитывая что комбинации количества настроек - конечны, это хороший результат. Да и кто будет открывать все настройки для гостей кроме как демосайт? P.S. при этом все сама папка кеша у нас весит 680Мб..
Задойный Алексей написал: Самая существенная проблема в том, что на материал могут взять на вооружение люди для вечного кеширования чего угодно, а не только того, что описали вы.
Си++ тоже позволяет программисту выстрелить себе в ногу, от этого он не становится плохим языком =) В статье же рассмотрен конкретный кейс, под который хорошо лег механизм кеширования в битриксе.
Морозов Артем написал: Эта статья как раз для "во-первых".
Коллеги, вы выше пишете, что использовали эти приёмы ещё в 1 битронике. А статья только сейчас вышла. И какое же это "предупреждение"? Да и потом она будет похоронена, а откуда среднестатистический начинающий разработчик/админ, столкнувшийся с вашим решением должен о ней узнать? Извините, но аргумент так себе. Повторюсь. Я не считаю ваш подход неверным. Просто он очень нестандартный. Это не обвинения с моей стороны.
Ну раз не разрастается, то и здорово. Просто всегда есть вероятность, что кто-нибудь из партнёров потом после вас неверно врезался в этот кусок (мало ли зачем) и случился армагедон. Просто кеш вырос до нескольких ГБ и всех убил. Я потому и спросил. Помню просто случаи в практике, когда кеш был сумасшедший. Больная тема.
Задойный Алексей написал: Да и потом она будет похоронена, а откуда среднестатистический начинающий разработчик/админ, столкнувшийся с вашим решением должен о ней узнать?
Вы правы, мы тоже думаем об этом. Сейчас ссылка на эту статью и на еще 2 предыдущие (по JS решения и статусах товаров) — есть в разделе "Документация" вкладки "Установка": http://marketplace.1c-bitrix.ru/solut...stall-link так же там есть ссылка на 2 видео-урока и FAQ, который регулярно пополняет наша техподдержка.
Вот мне тоже хочется чтобы мы стали более, что называется, "Developer Friendly". По этому начали выделять время на то чтобы делиться в блогах своими знаниями...
Задойный Алексей написал: оллеги, вы выше пишете, что использовали эти приёмы ещё в 1 битронике.
"Я вам не скажу за всю Одессу" по первому битронику, но там достаточно просто был механизм до ввода этого алгоритма. Подробнее наверное Илья расскажет.
Задойный Алексей написал: Да и потом она будет похоронена, а откуда среднестатистический начинающий разработчик/админ, столкнувшийся с вашим решением должен о ней узнать? Извините, но аргумент так себе.
Ну я пока не вижу проблем, там в коде все достаточно логично просматривается. все разложено пополочкам. В итоговом варианте это вообще черный ящик для конечного разработчика , он просто передал $arParams в функцию, а потом в любой момент в любом месте кода может их получить зная IDшник. Скажу только что есть уже планы как еще улучшить механизм и вообще свести на нет небольшие недостатки текущей реализации. Небольшой спойлер - я например вдохновился настройками композитного кеширования.
Задойный Алексей написал: C++ здесь приводить как пример не корректно.
Ну это же шутка была я даже смайлик поставил
P.S. А почему я не могу удалить или отредактировать свой коммент ? О_О
Морозов Артем написал: P.S. А почему я не могу удалить или отредактировать свой коммент ? О_О
владелец блога может сделать это за вас.
Морозов Артем написал: Ну я пока не вижу проблем, там в коде все достаточно логично просматривается. все разложено пополочкам.
Это не говорит ничего о том смогут ли ваш код понять потребители и/или другие разработчики. Это говорит лишь о том, что конкретно вы понимаете ваш код. Я вот тоже пару лет назад понял, что очень сильно оторвался от обычных редакторов контента и они зачастую меня просто не понимают.
В общем, моё дело - высказать опасения. Ваше дело их выслушать. =)
Задойный Алексей написал: Это не говорит ничего о том смогут ли ваш код понять потребители и/или другие разработчики. Это говорит лишь о том, что конкретно вы понимаете ваш код. Я вот тоже пару лет назад понял, что очень сильно оторвался от обычных редакторов контента и они зачастую меня просто не понимают.
Как сказал выше Роман Забродин нужно писать документацию, соответствующие таски уже поставлены и выполняются
Задойный Алексей написал: В общем, моё дело - высказать опасения. Ваше дело их выслушать. =)
Хм. А я тупо вынес параметры каталога в переменную, в отдельном файлике commonParams.php. Из минусов - редактирование параметров через визуальный редактор работает вероятно неожиданным образом. А остальное - как обычно. Нужна часть параметров - инклуд и по ключу массива. Ну а редактировать пхп код в редакторе изначально такая себе идея, тем более я часто использую константы для ид инфоблоков, из-за чего редактирование и так ломается.
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».