1С-Битрикс: Управление сайтомНа главную страницу
Клиентам
Маркетплейс
Партнерам
Разработчикам
Интеграция с 1С
Идея?


Личный кабинет
Авторизоваться
Регистрация
(войти) Корзина
Логин:

Пароль:



Забыли свой пароль?
Регистрация
Войти как пользователь:
Войти как пользователь
Вы можете войти на сайт, если вы зарегистрированы на одном из этих сервисов:
ВКонтакте
Мой Мир
Twitter
Facebook
Google
Livejournal
Яндекс
Rambler
Mail.Ru
Liveinternet
Blogger
OpenID
Используйте вашу учетную запись VKontakte.ru для входа на сайт.
Используйте вашу учетную запись Мой Мир@Mail.ru для входа на сайт.
Используйте вашу учетную запись на Twitter.com для входа на сайт.
Используйте вашу учетную запись на Facebook.com для входа на сайт.
Используйте вашу учетную запись Google для входа на сайт.
.livejournal.com
@yandex.ru
@rambler.ru
@mail.ru
http://www.liveinternet.ru/users/ /
.blogspot.com
OpenID:
  • Документация
    • Управление сайтом
    • Корпоративный портал
    • .NET Forge CMS
    • Отраслевые решения
    • Marketplace
    • Аренда приложений (SaaS)
  • Обучение и сертификация
    • Онлайн-курсы и сертификация
    • Учебные центры
    • Мое обучение
    • Учебные видеоролики
  • Центр поддержки
    • Поддержка
    • FAQ
    • Мои обращения
  • Сообщество
    • Блоги Битрикс
    • Блоги веб-разработчиков
    • Общие форумы
    • Веб-разработчики
      • Моя страница
      • Мои сообщения
      • Группы
      • Найти коллег
  • Cтатьи
    • Архив
Главная / Общение / Сообщество разработчиков / Лазарчик Евгений / Блог Блогович Блогов
  • Новая версия
  • Работа с характеристиками
  • Выгрузка скидок
  • Разбивка на каталоги
  • Свойства и изображения
  • Производительность

Некэшируемые области в *стандартных* компонентах

Профиль
Друзья
Группы
Блог Блогович Блогов

Лазарчик Евгений

Дата последнего входа: 07.03.2012 20:20:12

Некэшируемые области в *стандартных* компонентах

0
Лазарчик Евгений
21.04.201021:4121.04.2010 21:41:00
Вот здесь Виталий Оборин писал о том, как в самописных компонентах можно сделать некэшируемые области. С помощью удивительной магии девятой версии главного модуля можно пойти дальше и реализовать некэшируемые области в стандартных компонентах.

Зачем это нужно?
Для достижения максимальной гибкости без потери производительности. Кэширование выгодно только тогда, когда данные редко изменяются. Но что делать, если в целом содержимое компонента хорошо кэшируется, но в нем присутствует область, где выводятся некие персональные для каждого пользователя данные либо просто часто изменяющиеся данные? Например, нам хотелось бы взять стандартный компонент новостей и вставить в середину списка динамически генерируемый рекламный блок. В таких ситуациях помогут некэшируемые области.

Как это сделать?
Следующий код нужно подключить в вашем файле /bitrix/php_interface/init.php:
http://pastebin.com/8m14JxGb

Использование некэшируемых областей в шаблоне компонента проиллюстрируем примером.
template.php:
Код
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>
<?nciStart();?>

<?=ConvertTimeStamp(false, "FULL")?> - компонент закэширован<br />
<[#INSERT#]> - текущее время<br />

<?nciFinish($component)?>

component_epilog.php:
Код
<?if (!defined ("B_PROLOG_INCLUDED") || true !== B_PROLOG_INCLUDED) die();?>
<?=nciDisplay($component)?>

insert.php:
Код
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>
<?=ConvertTimeStamp(false, "FULL")?>


Обработка некэшируемых областей будет проводиться только в тех шаблонах компонентов, где вы укажете данный код, все остальные компоненты будут работать, как раньше.
Если вы пользуетесь каким-нибудь пользовательским движком шаблонизации, то весь служебный код можно вынести туда. Если кому-то интересно, могу предоставить код для Smarty.

Как это работает?
Некэшируемый файл component_epilog.php, появившийся в девятке, не имеет доступа к закэшированному HTML-коду шаблона. Поэтому в файле template.php вывод буферизуется и помещается в переменную $arResult["RESULT_HTML"], после чего данная переменная помечается как кэшируемая с помощью метода CBitrixComponent::SetResultCacheKeys. В component_epilog.php содержимое данной переменной просто выводится, предварительно заменяя некэшируемые вставки на результат выполнения соответствующего php-файла в папке шаблона (по методу Виталия Оборина).

Преимущества метода
Подобную задачу можно решать различными способами, каждый из которых обладает своими положительными и отрицательными сторонами. Основные преимущества продемонстрированного подхода: простота, легкость использования и главное - он действительно работает =)

Домашнее задание
Для достижения простоты и наглядности я не стал реализовывать некоторые фичи. Что можно усовершенствовать:
  • добавить возможность использования в некэшируемых областях массивов $arParams и $arResult
  • посыпать некэшируемые вставки солью, чтобы исключить даже малейшую вероятность ложного срабатывания
  • произвести интеграцию с движками шаблонизации


Disclaimer
Автор не несет ответственности за непреднамеренное порабощение Вселенной, которое может произойти при выполнении вышеуказанного кода =)
Приветствуются конструктивная критика, пожелания и готовые примеры доработки.

Лазарчик Евгений
21.04.201021:4121.04.2010 21:41:00
Просмотров:1347 Комментариев:11 0
*
 
Незарегистрированным пользователям запрещена вставка ссылок. Зарегистрируйтесь или авторизуйтесь.
*
Добавить комментарий
0
Sergey Leshchenko
22.04.2010 01:33:37
Я попридераюсь немного, можно?

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

Посмотрел в код nciDisplay() и сразу скажу, что не будет он корректно работать с методом $GLOBALS['APPLICATION']->ShowBanner() (а только он из коробки умеет выводить рекламу с таргетингом по ключевикам) или любыми другими отложенными функциями.
Ответить Ссылка 0
0
Яковенко Дмитрий
22.04.2010 01:40:42
Цитата
Посмотрел в код nciDisplay() и сразу скажу, что не будет он корректно работать с методом $GLOBALS['APPLICATION']->ShowBanner() (а только он из коробки умеет выводить рекламу с таргетингом по ключевикам) или любыми другими отложенными функциями.

Всё будет, писал я о подобной проблеме http://dev.1c-bitrix.ru/community/webdev/user/23706/blog/843/
Ответить Родитель Ссылка 0
0
Sergey Leshchenko
22.04.2010 03:56:47
А мы смотрим в код одной и той же функции?
Надеюсь, Евгений будет не против, если я приведу код этой функции здесь для наглядности:
Код
 
function nciDisplay (&$component) 
{ 
   $html = $component->arResult["RESULT_HTML"]; 
   preg_match_all ("~<[#(w+)#]>~", $html, $matches); 
    
   if (is_array ($matches)) 
   { 
      $template_path = $_SERVER["DOCUMENT_ROOT"].$component->arResult["TEMPLATE_PATH"]; 
      $keys = $matches[0]; 
      $vars = $matches[1]; 
       
      foreach ($keys as $key_index => $key_name) 
      { 
         ob_start(); 
         include ($template_path."/".(strtolower ($vars[$key_index])).".php"); 
         $mini_template_data = ob_get_clean (); 
         $html = str_replace ($key_name, $mini_template_data, $html); 
      } 
   } 
   return $html; 
} 

То что описано у вас - это фактически этот же подход только более глобальный и вызываемый непосредственно перед самым выводом буффера. Как недостаток - не имеет защиты от вставок пользователем и парсит весь контент страницы.

А... или вы предлагаете в подключаемом файле из эпилога компонента возвращать еще один маркер и добавлять обработчик события OnEndBufferContent для вывода баннера или содержимого отложенной функции? Ололо! smile:D
Ответить Родитель Ссылка 0
0
Яковенко Дмитрий
22.04.2010 09:47:35
Мой комент больше отностится не к посту, а к вашему комментарию
Цитата
$GLOBALS['APPLICATION']->ShowBanner()
ShowBanner это буферизированный результат ф-ции CAdvBanner::Show
Цитата
То что описано у вас - это фактически этот же подход только более глобальный и вызываемый непосредственно перед самым выводом буффера. Как недостаток - не имеет защиты от вставок пользователем и парсит весь контент страницы.

То что для вас недостаток, для меня преимущество smile8) именно это и требовалось.
Не исключено, что если есть component_after, то скоро появится component_before это решение тоже утратит актуальность. smile:D
Ответить Родитель Ссылка 0
0
Sergey Leshchenko
22.04.2010 19:47:16
Цитата
Мой комент больше отностится не к посту, а к вашему комментарию
Цитата$GLOBALS['APPLICATION']->ShowBanner()

ShowBanner это буферизированный результат ф-ции CAdvBanner::Show

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

Цитата
То что для вас недостаток, для меня преимущество именно это и требовалось.

Весьма сомнительное преимущество, но хозяин - барин.
Ответить Родитель Ссылка 0
0
Лазарчик Евгений
22.04.2010 10:48:28
Цитата
Как недостаток - не имеет защиты от вставок пользователем

В моем случае, когда области оформляются символами <[# #]>, пользователь не сможет их вставить, потому что присутствует символ <.
Для особо параноидальных можно посыпать вставки солью. А именно, в шаблоне вставка будет выглядеть как-то так:
Код
<?=nciInsert("INSERT")?>

Функция nciStart будет генерировать случайную строку, которая будет запоминаться в кэше и которая будет дописываться к коду всех вставок (например, <#[INSERT_a77c5d4904372a6893cae61531901ee1]#>). А в nciFinish будут производиться замены только тех вставок, к которым дописана именно та соль, которая сохранена в кэше.
Ответить Родитель Ссылка 0
0
Sergey Leshchenko
22.04.2010 20:24:46
Евгений, тот комментарий относился к решению, описанному в посте Дмитрия.

А про особо параноидальных отвечу, что поиск каких-либо решений этой якобы проблемы, затронутой в вашем топике, тоже не меньшая паранойя.
Нужны динамические вставки - выносите код шаблона из template.php в component_epilog.php шаблона, предварительно добавив нужные кэшируемые ключи, и не мучайтесь. Вот мое мнение.
Ответить Родитель Ссылка 0
0
Кудряшов Игорь
22.06.2011 15:55:05
Цитата
Нужны динамические вставки - выносите код шаблона из template.php в component_epilog.php шаблона, предварительно добавив нужные кэшируемые ключи

Интересна ваша идея, можно по подробней?
Ответить Родитель Ссылка 0
1
Sergey Leshchenko
22.06.2011 23:21:17
Написал заметку с описанием способа:
http://dev.1c-bitrix.ru/community/webdev/user/2854/blog/universal-method-of-eliminating-the-component-template-from-the-cache/
Ответить Родитель Ссылка 1
0
Лазарчик Евгений
22.04.2010 10:38:41
Честно говоря, я пока не задумывался об отложенных функциях. Показ рекламы в моем случае означал вывод случайного блока контекстной рекламы либо крутилки случайных элементов каталога.
Если позарез нужны отложенные функции, видимо, придется воспользоваться обработчиком OnEndBufferContent
Ответить Родитель Ссылка 0
0
leofantos
22.06.2011 16:57:57
Добрый день!
Вы бы не могли подсказать, как добавить возможность использования массивов $arParams и $arResult?
Ответить Ссылка 0

Добавить комментарий

Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».
 
Технологии Эрмитаж
BitrixMobile
Автокеширование
SiteUpdate
Производительность Виртуальная машина
Веб-окружение
Результаты тестов
Выбрать хостинг
Веб-кластер
Безопасность Проактивная защита
Веб-антивирус
Аутентификация

Контакты Поиск Карта сайта
Телефон: +7 (495) 229-14-41
Оставайтесь с нами: Facebook Twitter Habrahabr VKontakte Developers Google 1+
Как распознать QR код?Контакты QR


© 2001-2012 «Битрикс», «1С-Битрикс». Работает на 1С-Битрикс: Управление сайтом.
Английская версия Немецкая версия