- Кеширование выборки при ajax-запросе (CPHPCache)
- Кеширование выборки при ajax-запросе (D7)
- Реализация кеширования в компоненте средствами CPHPCache
- Кеширование выборок из БД (D7)
- function getSliders()
<?
define('TARGET_IBLOCK_ID', 1);
// Это то, что вернет скрипт
$arReturn = [
'result' => 'error',
'data' => 'Неправильный запрос',
];
$sCode = $_POST["code"];
if ( !empty($sCode) )
{
// Инициализируем php-кеширование (в хранилище кеша будет помещен json-объект)
$cache = new CPHPCache();
// Срок жизни кеша
$cache_time = 86400*7;
// Уникальный ID. Созданный кеш-файл будет именован его хеш-значением
$cache_id = 'sectCache'.$sCode;
// Папка для хранения кеша
$cache_path = '/sectCache/'.$sCode;
// Проверяем существование кеша
if ( $cache->InitCache($cache_time, $cache_id, $cache_path) )
{
// Кеш есть, достаем данные
$arCacheData = $cache->GetVars();
// Достаем по ключу, с которым положили
$arReturn['data'] = $arCacheData['sectCache'.$sCode];
}
else // Кеша нет, нужно получить данные
{
if ( CModule::IncludeModule('iblock') )
{
$arSelect = [
"ID",
"NAME",
"PROPERTY_YEAR",
];
// Фильтр лучше использовать всегда, иначе при ошибке будет выбор всех элементов
$arFilter = [
'IBLOCK_ID' => TARGET_IBLOCK_ID,
"ACTIVE" => "Y",
];
if ($sCode == "all-brands")
$arFilter['INCLUDE_SUBSECTIONS'] = 'Y';
else
$arFilter['SECTION_CODE'] = $sCode;
// Получаем данные
$res = \CIBlockElement::GetList(["ID"=>"DESC"], $arFilter, false, false, $arSelect);
// Массив элементов
$arItems = [];
while ($arElement = $res->Fetch())
{
$arElement["PREVIEW_PICTURE"] = CFile::GetPath($arElement["PREVIEW_PICTURE"]);
$arItems[$arElement['ID']] = $arElement;
}
// Сохраняем данные в кеш
// Чтобы кешировать HTML, заключите его между (start|end)DataCache()
$cache->StartDataCache($cache_time, $cache_id, $cache_path);
$cache->EndDataCache(['sectCache'.$sCode => $arItems]);
$arReturn['data'] = $arItems;
}
else
{
$arReturn['data'] = "Модуль инфоблоков не подключен";
}
}
}
die(json_encode($arReturn));
?>
<?
define('TARGET_IBLOCK_ID', 1);
// Это то, что вернет скрипт
$arReturn = [
'result' => 'error',
'data' => 'Неправильный запрос',
];
$sCode = \Bitrix\Main\Context::getCurrent()->getRequest()->getPost("code");
if (!empty($sCode))
{
$cache = \Bitrix\Main\Data\Cache::createInstance();
$cache_time = 86400*7;
$cache_id = 'sectCache'.$sCode;
$cache_path = '/sectCache/'.$sCode;
if ($cache->initCache($cache_time, $cache_id, $cache_path))
{
$arCachedVars = $cache->getVars();
$arReturn['data'] = $arCachedVars['sectCache'.$sCode];
}
else
{
if (!\Bitrix\Main\Loader::includeModule('iblock'))
{
$arReturn['data'] = "Модуль инфоблоков не подключен";
}
else
{
$res = \CIBlockElement::GetList(
array("ID" => "DESC"),
array('IBLOCK_ID' => TARGET_IBLOCK_ID, "ACTIVE" => "Y"),
false,
false,
array("ID", "NAME"),
);
$arItems = [];
while ($arElement = $res->fetch()) {
$arItems[ $arElement['ID'] ] = $arElement;
}
$cache->startDataCache();
$cache->endDataCache(['sectCache'.$sCode => $arItems]);
$arReturn['result'] = 'success';
$arReturn['data'] = $arItems;
}
}
}
die(json_encode($arReturn));
?>
<?
$obCache = new CPHPCache();
$cacheTTL = $arParams["CACHE_TIME"];
$cacheID = $arParams['IBLOCK_ID'] . $arParams['ELEMENT_ID'];
$cachePath = false;
// Проверяем существование актульного кеша
if ($obCache->InitCache($cacheTTL, $cacheID, $cachePath))
{
// Получаем переменные
$arVars = $obCache->GetVars();
$arResult = $arVars['arResult'];
// Выводим HTML-кеш
$obCache->Output();
}
// Иначе стартуем процесс кеширования
elseif ($obCache->StartDataCache())
{
$itemItems = CIBlockElement::GetList([], $arFilter, false, false, $arSelect);
while ($arItem = $itemItems->Fetch())
{
$arResult['ITEMS'][$arItem['ID']] = $arItem;
}
// Здесь же получаем итоговый HTML шаблона,
// который также кешируем
$this->IncludeComponentTemplate();
// Список переменных для кеширования
$obCache->EndDataCache([
'arResult' => $arResult,
]);
}
?>
<?
// Кеш по определенному тегу можно очистить так:
$GLOBALS['CACHE_MANAGER']->ClearByTag("iblock_id_5");
// также можно очистить кеш по подразделу хранения:
$obCache = new CPHPCache();
$obCache->CleanDir('/myCache'); // Очищаем наш кеш
$obCache->CleanDir(); // а так можно очистить вообще весь кеш
?>
В версии 16.5.9 в ORM появилось кеширование выборок из базы данных. Чтобы закешировать результат getList, нужно задать ключ cache.Например, при получении элементов инфоблока:
$res = \Bitrix\Iblock\ElementTable::getList(array(
'select' => array('ID', 'NAME', 'XML_ID'),
'filter' => array('IBLOCK_ID' => 1),
'cache' => array(
'ttl' => 60,
'cache_joins' => true,
)
));
$result = $res->fetch();
Параметров ttl задаётся время жизни кеша, а cache_joins задаёт необходимость кеширования при наличии джойнов. Внутри используется управляемое кеширование. Кеш пишется в папку /bitrix/managed_cache/MYSQL/orm_%имя_таблицы_сущности_orm%/
с ключом md5(%sql-запрос%).
В настройках CMS /bitrix/.settings.php
можно задать глобальный диапазон ttl для отдельных таблиц с помощью настройки cache_flags:
'cache_flags' => array(
'value'=> array(
"b_iblock_element_min_ttl" => 60,
"b_iblock_element_max_ttl" => 86400,
)
),
Для того, чтобы очистить кеш выборок сущности, нужно вызвать метод cleanCache. Например, для элементов инфоблока:
\Bitrix\Iblock\ElementTable::getEntity()->cleanCache();
<?
function getSliders($iblock_id)
{
$cache = new CPHPCache();
$cache_time = 3600;
$cache_id = 'sliders' . $iblock_id;
$cache_path = 'sliders';
if ($cache->InitCache($cache_time, $cache_id, $cache_path))
{
$vars = $cache->GetVars();
if (is_array($vars["sliders"]) && count($vars["sliders"]))
$sliders = $vars["sliders"];
}
if (!is_array($sliders))
{
$query_rows = $GLOBALS['DB']->Query("
SELECT b.ID as id, b.NAME as name, b.PREVIEW_PICTURE as picCode, b.PREVIEW_TEXT as url
FROM b_iblock_element b
WHERE b.IBLOCK_ID = 10 AND b.ACTIVE='Y'
ORDER BY b.SORT ASC
");
while ($slider = $query_rows->Fetch())
{
$sliders[$slider['id']] = $slider;
$sliders[$slider['id']]['pic'] = CFile::GetPath($slider['picCode']);
}
$cache->StartDataCache($cache_time, $cache_id, $cache_path);
$cache->EndDataCache(["sliders" => $sliders]);
}
return $sliders;
}
?>