Битрикс. Классы CPHPCache и Cache
04.11.2018
Теги: CMS • Web-разработка • Битрикс • Кеширование • Класс • НовоеЯдро • ОтложенныеФункции • СтароеЯдро
Кеширование позволяет уменьшить нагрузку на аппаратные ресурсы, таким образом влияя на время отклика сайта. Используется как в стандартных компонентах, так и в компонентах, разработанных под свои нужды. Результаты ресурсоемких, а так же редко обновляемых кусков кода заносятся в кеш, при повторном запросе результат выдается из кеша.
Старое ядро
В старом ядре Битрикс для кеширования есть два класса — это CPageCache
и CPHPCache
. Первый служит для кеширования сформированного HTML-кода, второй — для кеширования HTML-кода и PHP-переменных. Файлы кеша записываются в каталог /bitrix/cache/
.
Класс CPageCache
// подключаем модуль «Информационные блоки» if (!CModule::IncludeModule('iblock')) { ShowError('Модуль «Информационные блоки» не установлен'); } // тип инфоблока, откуда будем получать элемент инфоблока $iblockType = 'content'; // идентификатор инфоблока, откуда будем получать элемент $iblockId = 5; // идентификатор элемента инфоблока, который надо показать $elementId = 354; // создаем объект кеша $pageCache = new CPageCache(); // время кеширования в секундах $cacheTime = 3600; // формируем идентификатор кеша в зависимости от всех параметров, // которые могут повлиять на результирующий HTML-код $cacheId = $iblockType.$elementId; // директороия для хранения файлов кеша $cacheDir = '/some-cache-dir'; // начинаем буферизацию вывода if ($pageCache->StartDataCache($cacheTime, $cacheId, $cacheDir)) { // выбираем из базы данных элемент инфоблока if ($arElement = GetIBlockElement($elementId, $iblockType)) { // выводим заголовок страницы echo '<h1>'.$arElement['NAME'].'</h1>', PHP_EOL; // выводим картинку echo CFile::ShowImage($arElement['DETAIL_PICTURE'], 500, 500), PHP_EOL; // выводим краткое описание echo '<p>'.$arElement['PREVIEW_TEXT'].'</p>'; // записываем буферизированный вывод в файл кеша $pageCache->EndDataCache(); } else { $pageCache->AbortDataCache(); \Bitrix\Iblock\Component\Tools::process404( 'Страница не найдена', true, true ); } }
$cacheDir
начинается со слеша и им не заканчивается. При использовании в качестве кеша memcached
это будет критичным при сбросе кеша.
Файл кеша /bitrix/cache/some-cache-dir/47/476bb6ea1797242d5401ed9ec02c831e.html
содержит в себе отметку времени (функция time()
) — когда она станет меньше текущей, кеш уже не актуален:
BX001541320265001541320265<h1>Ангорская кошка</h1>
<img src="/upload/iblock/57f/57f3872d827b2a94d61be9c999556d4b.jpg" border="0" alt="" width="500" height="500" />
<p>Ангорская кошка — порода домашних кошек, которая была создана европейскими и американскими селекционерами на
основе группы особей, вывезенных из Зоопарка Анкары в середине XX века. Турецкая ангора не только умна, но и
чрезвычайно адаптивна, ласкова и игрива.</p>
Класс CPHPCache
Пример кеширования PHP-переменных:
// подключаем модуль «Информационные блоки» if (!CModule::IncludeModule('iblock')) { ShowError('Модуль «Информационные блоки» не установлен'); } // тип инфоблока, откуда будем получать элемент инфоблока $iblockType = 'content'; // идентификатор инфоблока, откуда будем получать элемент $iblockId = 5; // идентификатор элемента инфоблока, который надо показать $elementId = 354; // если что-то пошло не так, эта переменная примет значение true $notFound = false; // создаем объект кеша $phpCache = new CPHPCache(); // время кеширования в секундах $cacheTime = 3600; // формируем идентификатор кеша в зависимости от всех параметров, // которые могут повлиять на PHP-переменные $cacheId = $iblockType.$elementId; // если кеш есть и он еще актуален if ($phpCache->InitCache($cacheTime, $cacheId, '/other-cache-dir')) { /* * получаем закешированные переменные */ $data = $phpCache->GetVars(); // данные об инфоблоке $iblockName = $data['iblockName']; $listPageURL = $data['listPageURL']; // данные об элементе инфоблока $elementName = $data['elementName']; $elementPicture = $data['elementPicture']; $elementPreview = $data['elementPreview']; } else { /* * иначе обращаемся к базе */ // данные об инфоблоке $arIblock = GetIBlock($iblockId, $iblockType); // данные об элементе инфоблока $arElement = GetIBlockElement($elementId, $iblockType); // если данные успешно получены if ($arIblock && $arElement) { $iblockName = $arIblock['NAME']; $listPageURL = $arIblock['LIST_PAGE_URL']; $elementName = $arElement['NAME']; $elementPicture = $arElement['DETAIL_PICTURE']; $elementPreview = $arElement['PREVIEW_TEXT']; // записываем полученные данные в кеш $phpCache->StartDataCache(); $phpCache->EndDataCache( array( 'iblockName' => $iblockName, 'listPageURL' => $listPageURL, 'elementName' => $elementName, 'elementPicture' => $elementPicture, 'elementPreview' => $elementPreview ) ); } else { // что-то пошло не так $notFound = true; } } if (!$notFound) { // все хорошо, все данные получены // в заголовок страницы вставим название элемента $APPLICATION->SetTitle($elementName); // добавим пункт меню в навигационную цепочку $APPLICATION->AddChainItem($iblockName, $listPageURL); // выводим заголовок страницы echo '<h1>'.$elementName.'</h1>', PHP_EOL; // выводим картинку echo CFile::ShowImage($elementPicture, 500, 500), PHP_EOL; // выводим краткое описание echo '<p>'.$elementPreview.'</p>'; } else { // что-то пошло не так \Bitrix\Iblock\Component\Tools::process404( 'Страница не найдена', true, true ); }
Файл кеша /bitrix/cache/other-cache-dir/47/476bb6ea1797242d5401ed9ec02c831e.php
:
<? if ($INCLUDE_FROM_CACHE!='Y') return false; $datecreate = '001541323175'; $dateexpire = '001541326775'; $ser_content = 'a:2:{s:7:"CONTENT";s:0:"";s:4:"VARS";a:5:{s:10:"iblockName";s:49:"Статьи о домашних животных";s:11:"listPageURL";s:10:"/articles/";s:11:"elementName";s:29:"Ангорская кошка";s:14:"elementPicture";s:4:"1025";s:14:"elementPreview";s:473:"Ангорская кошка — порода домашних кошек, которая была создана европейскими и американскими селекционерами на основе группы особей, вывезенных из Зоопарка Анкары в середине XX века. Турецкая ангора не только умна, но и чрезвычайно адаптивна, ласкова и игрива.";}}'; return true; ?>
Еще один пример — в кеш сохраняется HTML-код и PHP-переменные:
// подключаем модуль «Информационные блоки» if (!CModule::IncludeModule('iblock')) { ShowError('Модуль «Информационные блоки» не установлен'); } // тип инфоблока, откуда будем получать элемент инфоблока $iblockType = 'content'; // идентификатор инфоблока, откуда будем получать элемент $iblockId = 5; // идентификатор элемента инфоблока, который надо показать $elementId = 354; // создаем объект кеша $phpCache = new CPHPCache(); // время кеширования в секундах $cacheTime = 3600; // формируем идентификатор кеша в зависимости от всех параметров, // которые могут повлиять на HTML-код и PHP-переменные $cacheId = $iblockType.$elementId; // если кеш есть и он еще актуален if ($phpCache->InitCache($cacheTime, $cacheId, '/other-cache-dir')) { // получаем закешированные переменные $data = $phpCache->GetVars(); $iblockName = $data['iblockName']; $listPageURL = $data['listPageURL']; } else { // иначе обращаемся к базе $data = GetIBlock($iblockId, $iblockType); $iblockName = $data['NAME']; $listPageURL = $data['LIST_PAGE_URL']; } // в заголовок страницы вставим название инфоблока $APPLICATION->SetTitle($iblockName); // добавим пункт меню в навигационную цепочку $APPLICATION->AddChainItem($iblockName, $listPageURL); // начинаем буферизацию вывода if ($phpCache->StartDataCache()) { // выбираем из базы данных элемент инфоблока if ($arElement = GetIBlockElement($elementId, $iblockType)) { // выводим заголовок страницы echo '<h1>'.$arElement['NAME'].'</h1>', PHP_EOL; // выводим картинку echo CFile::ShowImage($arElement['DETAIL_PICTURE'], 500, 500), PHP_EOL; // выводим краткое описание echo '<p>'.$arElement['PREVIEW_TEXT'].'</p>'; // записываем предварительно буферизированный вывод в файл кеша // вместе с дополнительными переменными $phpCache->EndDataCache( array( 'iblockName' => $iblockName, 'listPageURL' => $listPageURL ) ); } else { $phpCache->AbortDataCache(); \Bitrix\Iblock\Component\Tools::process404( 'Страница не найдена', true, true ); } }
SetTitle()
и AddChainItem()
вызываются за пределами HTML-кеша.
Файл кеша /bitrix/cache/other-cache-dir/47/476bb6ea1797242d5401ed9ec02c831e.php
:
<? if ($INCLUDE_FROM_CACHE!='Y') return false; $datecreate = '001541406065'; $dateexpire = '001541409665'; $ser_content = 'a:2:{s:7:"CONTENT";s:671:"<h1>Ангорская кошка</h1> <img src="/upload/iblock/57f/57f3872d827b2a94d61be9c999556d4b.jpg" border="0" alt="" width="500" height="500" /> <p>Ангорская кошка — порода домашних кошек, которая была создана европейскими и американскими селекционерами на основе группы особей, вывезенных из Зоопарка Анкары в середине XX века. Турецкая ангора не только умна, но и чрезвычайно адаптивна, ласкова и игрива.</p>";s:4:"VARS";a:2:{s:10:"iblockName";s:49:"Статьи о домашних животных";s:11:"listPageURL";s:10:"/articles/";}}'; return true; ?>
Новое ядро
Аналогом CPHPCache
в новом ядре является класс \Bitrix\Main\Data\Cache
. Основные различия в методах в том, что названия методов нового класса пишутся с прописной буквы в соответствии с новыми требования оформления кода. В остальном внешне изменений практически нет:
use \Bitrix\Main\Data\Cache, \Bitrix\Main\Loader, \Bitrix\Iblock\Component\Tools; // подключаем модуль «Информационные блоки» if (!Loader::includeModule('iblock')) { ShowError('Модуль «Информационные блоки» не установлен'); } // тип инфоблока, откуда будем получать элемент инфоблока $iblockType = 'content'; // идентификатор инфоблока, откуда будем получать элемент $iblockId = 5; // идентификатор элемента инфоблока, который надо показать $elementId = 354; // если что-то пошло не так, эта переменная примет значение true $notFound = false; // получаем экземпляр класса $cache = Cache::createInstance(); // время кеширования в секундах $cacheTime = 3600; // формируем идентификатор кеша $cacheId = $iblockType.$elementId; if ($cache->initCache($cacheTime, $cacheId, '/another-cache-dir')) { /* * получаем закешированные переменные */ $data = $cache->getVars(); // данные об инфоблоке $iblockName = $data['iblockName']; $listPageURL = $data['listPageURL']; // данные об элементе инфоблока $elementName = $data['elementName']; $elementPicture = $data['elementPicture']; $elementPreview = $data['elementPreview']; } elseif ($cache->startDataCache()) { /* * иначе обращаемся к базе */ // данные об инфоблоке $arIblock = GetIBlock($iblockId, $iblockType); // данные об элементе инфоблока $arElement = GetIBlockElement($elementId, $iblockType); // если данные успешно получены if ($arIblock && $arElement) { $iblockName = $arIblock['NAME']; $listPageURL = $arIblock['LIST_PAGE_URL']; $elementName = $arElement['NAME']; $elementPicture = $arElement['DETAIL_PICTURE']; $elementPreview = $arElement['PREVIEW_TEXT']; // записываем полученные данные в кеш $cache->endDataCache( array( 'iblockName' => $iblockName, 'listPageURL' => $listPageURL, 'elementName' => $elementName, 'elementPicture' => $elementPicture, 'elementPreview' => $elementPreview ) ); } else { // что-то пошло не так $cache->abortDataCache(); $notFound = true; } } if (!$notFound) { // все хорошо, все данные получены // в заголовок страницы вставим название элемента $APPLICATION->SetTitle($elementName); // добавим пункт меню в навигационную цепочку $APPLICATION->AddChainItem($iblockName, $listPageURL); // выводим заголовок страницы echo '<h1>'.$elementName.'</h1>', PHP_EOL; // выводим картинку echo CFile::ShowImage($elementPicture, 500, 500), PHP_EOL; // выводим краткое описание echo '<p>'.$elementPreview.'</p>'; } else { // что-то пошло не так Tools::process404( 'Страница не найдена', true, true ); }
Файл кеша /bitrix/cache/another-cache-dir/47/476bb6ea1797242d5401ed9ec02c831e.php
:
<? if ($INCLUDE_FROM_CACHE!='Y') return false; $datecreate = '001541325078'; $dateexpire = '001541328678'; $ser_content = 'a:2:{s:7:"CONTENT";s:0:"";s:4:"VARS";a:5:{s:10:"iblockName";s:49:"Статьи о домашних животных";s:11:"listPageURL";s:10:"/articles/";s:11:"elementName";s:29:"Ангорская кошка";s:14:"elementPicture";s:4:"1025";s:14:"elementPreview";s:473:"Ангорская кошка — порода домашних кошек, которая была создана европейскими и американскими селекционерами на основе группы особей, вывезенных из Зоопарка Анкары в середине XX века. Турецкая ангора не только умна, но и чрезвычайно адаптивна, ласкова и игрива.";}}'; return true; ?>
Очистить кеш, сохраненный в директории /bitrix/cache/another-cache-dir/
можно следующим образом:
$cache = \Bitrix\Main\Data\Cache::createInstance(); $cache->cleanDir('/another-cache-dir');
Очистить весь кеш (т.е. все содержимое директории /bitrix/cache/
):
$cache = \Bitrix\Main\Data\Cache::createInstance(); $cache->cleanDir();
Этот код промаркирует директрии кеша на удаление:
[bitrix]
[cache]
[another-cache-dir.~917285]
[other-cache-dir.~578322]
[some-cache-dir.~881386]
..........
В конце названий всех директорий появится приписка из точки, тильды и длинного числа. После такой маркировки пути к файлам кеша изменятся, следовательно весь старый кеш сайта не будет восприниматься. Остаётся только все это удалить. И система сама это сделает: по агентам на хитах или кроне. Причём небольшими порциями, по несколько файлов за итерацию.
Поиск: CMS • Web-разработка • Битрикс • Класс • Кеширование • CPageCache • CPHPCache • Cache • StartDataCache • EndDataCache • AbortDataCache • InitCache • GetVars • createInstance • cleanDir • Старое ядро • Новое ядро • Отложенные функции