Working with cache in Bitrix D7, Bitrix24
Rus
Eng
Работа с кешем в Битрикс D7, Битрикс24

All English-language materials have been translated fully automatically using the Google service

Clearing the Bitrix modules cache

Quite often, during development in Bitrix24, fragments of code remain deleted, but saved using the cache. For example, recent conversations or a list of recent groups. In this case, it is enough to simply get rid of them by running the command:

BXClearCache( true, "/bx/imc/recent/");

or

BXClearCache( true, "/bx/group/");

Clearing the component cache

If during development you need to programmatically clear the cache of a component, then you can use the OnBeforeIBlockElementUpdate function in init.php

AddEventHandler("iblock", "OnBeforeIBlockElementUpdate", Array("updateCacheClass", "OnBeforeIBlockElementUpdateHandler"));
class updateCacheClass{
    function OnBeforeIBlockElementUpdateHandler(&$arFields) {
        if ($arFields['IBLOCK_ID'] == 3) {
            CBitrixComponent::clearComponentCache('simplecomp:simplecomp.exam4');
        }
    }
}

Cache infoblock output

Make light cached output of infoblock elements

CModule::IncludeModule("iblock");
$cntIBLOCK_List = 19;
$cache = new CPHPCache();
$cache_time = 3600*12; //кеш на сутки
$cache_id = 'arIBlockListID'.$cntIBLOCK_List;
$cache_path = 'arIBlockListID';
if ($cache_time > 0 && $cache->InitCache($cache_time, $cache_id, $cache_path))
{
    $res = $cache->GetVars();
    if (is_array($res["arIBlockListID"]) && (count($res["arIBlockListID"]) > 0)){
        $arIBlockListID = $res["arIBlockListID"];
    }
    $arIBlockListID['CACHE']='true';

}
if (!is_array($arIBlockListID))
{
    $arIBlockListID['CACHE']='false';
    $arIBlockListID['NAME']=CIBlock::GetArrayByID($cntIBLOCK_List, "NAME");
    $arIBlockListID['DESCRIPTION']=CIBlock::GetArrayByID($cntIBLOCK_List, "DESCRIPTION");
    $arIBlockListID['PICTURE']=CFile::GetPath(CIBlock::GetArrayByID($cntIBLOCK_List, "PICTURE"));

    $arSelect = array("ID", "NAME", "CODE",'PREVIEW_TEXT','PREVIEW_PICTURE','PROPERTY_MORE_PHOTOS');
    $arFilter = array("IBLOCK_ID" => intval($cntIBLOCK_List),"IBLOCK_TYPE" => 'content', "ACTIVE_DATE" => "Y", "ACTIVE" => "Y");
    $rsImplementation = CIBlockElement::GetList(Array(), $arFilter, false, array(), $arSelect);

    while ($arImplementation = $rsImplementation->GetNextElement()) {
        $arItem = $arImplementation->GetFields();
        $arIBlockListID[$arItem['ID']]=$arItem;
    }

    //////////// end cache /////////
    if ($cache_time > 0)
    {
        $cache->StartDataCache($cache_time, $cache_id, $cache_path);
        $cache->EndDataCache(array("arIBlockListID"=>$arIBlockListID));
    }
}

Updating the value of a cached variable

A quick and not entirely elegant solution to update a variable in a cached component / template is to add code to component_epilog.php

<? global $CITY; ?>

<script type="text/javascript">
	$(document).ready(function() {
		$('#TOWN').val('<?=$CITY['NAME']?>');
	});
</script>

Two different types of component caching

In most of the standard Bitrix components, caching of the $ arResult array and the html code is used simultaneously. However, when writing your own components, this is not always convenient, it often happens that you need to execute some code in the template on each hit, so it's better to cache only the data in $ arResult. Below I gave 2 examples of caching (for component.php) - with and without html code caching. Please note that in the second option, the template is connected after the caching block, and $ this-> EndResultCache () takes its place.

Caching $ arResult and template html-code:

if($this->startResultCache(false, array(($arParams["CACHE_GROUPS"]==="N"? false: $USER->GetGroups())))){
   if(!Loader::includeModule("iblock"))   {
      $this->abortResultCache();
      ShowError("Iblock module not installed");
      return;
   }
   $this->includeComponentTemplate();
}

Caching $arResult only:

if($this->startResultCache(false, array(($arParams["CACHE_GROUPS"]==="N"? false: $USER->GetGroups())))){
   if(!Loader::includeModule("iblock")){
      $this->abortResultCache();
      ShowError("Iblock module not installed");
      return;
   }
   $this->EndResultCache();
}
$this->includeComponentTemplate();

Add data to the cache from a template for use in component_epilog.php

Component_epilog.php is a file that runs after the template is rendered and is not cached, i.e. it runs regardless of whether the newly generated html code was shown from the template or output from the cache. Accordingly, we can use this file to perform some actions on each hit, even, for example, display the html code above on the page using deferred functions. But the data available in component_epilog.php tends to be quite limited in components that use html caching. In this example, I will show how to expand the list of this data, for this we will insert the following code into the result_modifier.php file in the component template (For example, the key "ITEMS" in the $ arResult array is used, containing the main component in the "bitrix: news.list" data array):

if (is_object($this->__component)){ 
    $this->__component->SetResultCacheKeys(array('ITEMS')); 
    if (!isset($arResult['ITEMS'])) 
        $arResult['ITEMS'] = $this->__component->arResult['ITEMS']; 
}

Writing $ arResult of the parent complex component from the template

Sometimes in the template files of a complex component (which do not have their own cache) it is convenient to have some data from the usual (non-complex) components used in them. Example: after connecting the catalog.section.list component, in accordance with the structure of the html-code provided by the layout designer, we need access to some section fields in the template of the complex component. To avoid additional queries to the database and the associated inevitable caching, or reconnecting the catalog.section.list component, let's do this:

Let's add all the necessary data to the component cache, for example, use the result_modifier.php file to add the $ arResult ["SECTION"] array

if (is_object($this->__component)){ 
    $this->__component->SetResultCacheKeys(array('SECTION')); 
    if (!isset($arResult['SECTION'])) 
        $arResult['SECTION'] = $this->__component->arResult['SECTION']; 
}

In the component_epilog.php file, get the parent component object, if available, and use its arResult property to write the value

if(is_object($this->__parent))
   if($this->__parent->arResult)
      $this->__parent->arResult["SECTION_DEPTH_LEVEL"] = $arResult["SECTION"]["DEPTH_LEVEL"];

In a complex component template, the value will be available in the $ arResult variable

$arResult["SECTION_DEPTH_LEVEL"]

We cache data in $ arResult instead of html-code in regular components (from the template)

If you need to perform some manipulations with the data after creating the cache (for example, sorting the list of offices by distance from the current location), then the usual caching of the html code in the news.list component will not work. To cache the data in $ arResult, and not the generated html code, you can do the following:

Use the result_modifier.php file to add the $ arResult ["ITEMS"] array

if (is_object($this->__component)){ 
    $this->__component->SetResultCacheKeys(array('ITEMS')); 
    if (!isset($arResult['ITEMS'])) 
        $arResult['ITEMS'] = $this->__component->arResult['ITEMS']; 
}

The template output itself will be placed not in template.php, but in component_epilog.php (in this case, even after creating the cache, we will have access to the $ arResult ["ITEMS"] array).

Getting rid of the message "Cannot find '' template with page ''"

This cryptic message is generated if the specified template was not found when connecting the component. However, there are times (although quite exotic) when this message may be inappropriate. So that in the absence of a template, the component does not display this message, but returns false, we include the template inside the component instead of the standard "$ this-> IncludeComponentTemplate ();" as follows

if (!$this->__bInited) 
    return false; 

if ($this->InitComponentTemplate("", $this->siteTemplateId, "")) { 
    $this->showComponentTemplate(); 
    if($this->__component_epilog) 
        $this->includeComponentEpilog($this->__component_epilog); 

    return true; 
}else{ 
    return false; 
}

Disable the ability to edit component parameters

A very common case. It is by no means useful for all components to allow editing their parameters, especially if the call of the component is in the files header.php, footer.php, etc. To prohibit editing the parameters of a component in edit mode, in the fifth parameter of the $ APPLICATION-> IncludeComponent function, insert next array:

Array("HIDE_ICONS"=>"Y")

Script for automatic cache clearing

if (empty($_SERVER['DOCUMENT_ROOT'])) {
    $_SERVER['DOCUMENT_ROOT'] = realpath(__DIR__).'/../../../';
}

define('BX_BUFFER_USED', true);
define('NO_KEEP_STATISTIC', true);
define('NOT_CHECK_PERMISSIONS', true);
define('NO_AGENT_STATISTIC', true);
define('STOP_STATISTICS', true);
define('SITE_ID', 's1');

require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php';

BXClearCache(true);

if (class_exists('\Bitrix\Main\Data\ManagedCache')) {
    (new \Bitrix\Main\Data\ManagedCache())->cleanAll();
}

if (class_exists('\CStackCacheManager')) {
    (new \CStackCacheManager())->CleanAll();
}

if (class_exists('\Bitrix\Main\Data\StaticHtmlCache')) {
    \Bitrix\Main\Data\StaticHtmlCache::getInstance()->deleteAll();
}

Original here

Another option here

Material used:

Comments

There are no comments yet, you can be the first to leave it

Leave a comment

The site uses a comment pre-moderation system, so your message will be published only after approval by the moderator

You are replying to a user's comment

Send

FEEDBACK

Email me

Are you developing a new service, making improvements to the existing one and want to be better than your competitors? You have come to the right place. I offer you a comprehensive studio-level website development. From me you can order design, layout, programming, development of non-traditional functionality, implementation of communication between CMS, CRM and Data Analitics, as well as everything else related to sites, except for promotion.

Contact, I will always advise on all questions and help you find the most effective solution for your business. I am engaged in the creation of sites in Novosibirsk and in other regions of Russia, I also work with the CIS countries. You will be satisfied with our cooperation

An error occurred while sending, please try again after a while
Message sent successfully

Phones

+7(993) 007-18-96

Email

info@tichiy.ru

Address

Россия, г. Москва

By submitting the form, you automatically confirm that you have read and accept the Privacy Policy site

Contact with me
Send message
By submitting the form, you automatically confirm that you have read and accept Privacy policy of site
Sending successful!
Thank you for contacting :) I will contact you as soon as possible
Sending failed
An error occurred while sending the request. Please wait and try again after a while or call my phone number