Работа с PHP при создании решений на 1С-Битрикс

Раздел: Разработка на PHP и Битрикс -> Основы Битрикс

Основы работы с PHP в среде 1С-Битрикс

При разработке на платформе 1С-Битрикс каждый PHP-разработчик сталкивается с необходимостью интеграции собственной логики. Ниже представлены основные подходы, их варианты, типичные ошибки и способы их устранения.

Основное эффективное решение – создание компонента с наследованием от \CBitrixComponent. Это даёт гибкость, кеширование и правильную архитектуру.

Пример базовой структуры:


// /local/components/my/component/class.php
class CMyComponent extends \CBitrixComponent
{
    public function executeComponent()
    {
        $this->arResult['ITEMS'] = $this->getItems();
        $this->includeComponentTemplate();
    }

    private function getItems()
    {
        // логика получения данных
        return [];
    }
}
  

1с битрикс php (1с-битрикс и php)

В шаблоне (template.php) данные выводятся через $arResult. Компонент регистрируется в .description.php.

Проблема: отсутствие метода executeComponent – ошибка «Компонент не найден». Решение: обязательно реализовать данный метод.

Ошибка: глобальные переменные внутри класса. Решение: использовать $this->arParams и $this->arResult.

Как получить список элементов инфоблока с кешированием?

Используем CIBlockElement::GetList и оборачиваем в штатный кеш Битрикса:


$cache = \Bitrix\Main\Data\Cache::createInstance();
$cacheTime = 3600;
$cacheId = 'my_element_list';
$cacheDir = '/my_cache/';

if ($cache->initCache($cacheTime, $cacheId, $cacheDir)) {
    $arResult = $cache->getVars();
} elseif ($cache->startDataCache()) {
    $arResult = [];
    $res = CIBlockElement::GetList([], ['IBLOCK_ID' => 1], false, [], ['ID', 'NAME']);
    while ($item = $res->Fetch()) {
        $arResult[] = $item;
    }
    $cache->endDataCache($arResult);
}
  

Типичная ошибка: кеш не инвалидируется при изменении данных. Решение: использовать тегированный кеш или метод AbortDataCache при ошибке.

Как создать обработчик события (например, перед добавлением элемента)?


// /local/php_interface/init.php
AddEventHandler('iblock', 'OnBeforeIBlockElementAdd', 'MyBeforeAddHandler');

function MyBeforeAddHandler(&$arFields)
{
    if ($arFields['IBLOCK_ID'] == 1) {
        $arFields['NAME'] = '[Проверено] ' . $arFields['NAME'];
    }
}
  

Ошибка: изменение полей без проверки прав. Решение: всегда проверять $arFields['IBLOCK_ID'] и тип события.

Как выполнить произвольный PHP-код в публичной части?

Вариант через $APPLICATION->IncludeFile:


<?php
$APPLICATION->IncludeFile(
    '/local/include/my_code.php',
    ['PARAM' => 'value'],
    ['MODE' => 'php']
);
?>
  

В файле my_code.php можно писать любой PHP, но лучше использовать компоненты.

Ошибка: прямой вывод без учёта кеша – снижение производительности. Решение: оборачивать включение в управляемый кеш.

Заключение: выбор метода зависит от задачи. Компоненты – стандарт, кеш – обязателен, события – для глобальной логики. Избегайте глобальных переменных и прямых запросов к БД.

Дополнительные примеры с пошаговым разбором.

Пример 1: Компонент со сложной логикой и тегированным кешем

Пример

// class.php
use Bitrix\Main\Data\TaggedCache;

class CMyTaggedComponent extends \CBitrixComponent
{
    public function executeComponent()
    {
        $taggedCache = \Bitrix\Main\Data\TaggedCache::getInstance();
        $cache = \Bitrix\Main\Data\Cache::createInstance();
        $cacheTime = 3600;
        $cacheId = 'my_tagged_' . $this->arParams['IBLOCK_ID'];
        $cacheDir = '/my_tagged/';

        if ($cache->initCache($cacheTime, $cacheId, $cacheDir)) {
            $this->arResult = $cache->getVars();
        } elseif ($cache->startDataCache()) {
            $taggedCache->startTagCache($cacheDir);
            $taggedCache->registerTag('iblock_id_' . $this->arParams['IBLOCK_ID']);

            $this->arResult['ITEMS'] = $this->getItems();

            $taggedCache->endTagCache();
            $cache->endDataCache($this->arResult);
        }

        $this->includeComponentTemplate();
    }

    private function getItems()
    {
        // сложная выборка
        $items = [];
        $res = \CIBlockElement::GetList(
            ['SORT' => 'ASC'],
            ['IBLOCK_ID' => $this->arParams['IBLOCK_ID'], 'ACTIVE' => 'Y'],
            false,
            false,
            ['ID', 'NAME', 'DETAIL_PAGE_URL']
        );
        while ($item = $res->GetNext()) {
            $items[] = $item;
        }
        return $items;
    }
}

Результат: при изменении элементов инфоблока с ID = 1 кеш автоматически сбрасывается благодаря тегу.

Пример 2: Работа с ORM – выборка через DataManager

Пример

use Bitrix\Iblock\ElementTable;
use Bitrix\Main\Entity\Query;

$query = new Query(ElementTable::getEntity());
$query->setSelect(['ID', 'NAME', 'IBLOCK_ID']);
$query->setFilter(['=IBLOCK_ID' => 1, '=ACTIVE' => 'Y']);
$query->setOrder(['ID' => 'DESC']);
$query->setLimit(10);

$result = $query->exec();
$items = [];
while ($row = $result->fetch()) {
    $items[] = $row;
}

echo '<pre class="ex_r">' . print_r($items, true) . '</pre>';

Результат: массив с ID, NAME, IBLOCK_ID для первых 10 активных элементов.

Пример 3: Создание агента для периодической очистки кеша
Пример

// /local/php_interface/init.php
function clearMyCacheAgent(): string
{
    $cache = \Bitrix\Main\Data\Cache::createInstance();
    $cache->cleanDir('/my_tagged/');
    return 'clearMyCacheAgent();';
}

// Добавление агента (выполнить один раз)
CAgent::AddAgent(
    'clearMyCacheAgent();',
    '',
    'N',
    86400,
    '',
    'Y',
    date('d.m.Y H:i:s', time() + 86400)
);

Результат: агент запускается раз в сутки и очищает указанную кеш-директорию.

Пример 4: Обработчик события с модификацией полей и логгированием

Пример

AddEventHandler('iblock', 'OnAfterIBlockElementAdd', 'logNewElement');

function logNewElement(&$arFields)
{
    $logFile = $_SERVER['DOCUMENT_ROOT'] . '/upload/element_log.txt';
    $message = date('Y-m-d H:i:s') . ' | ID=' . $arFields['ID'] . ' | Name=' . $arFields['NAME'] . "\n";
    file_put_contents($logFile, $message, FILE_APPEND);
}

Результат: при добавлении элемента в любой инфоблок в лог-файл записывается строка с ID и именем.

Примечание: во всех примерах используйте исключительно классы и функции ядра Битрикс для совместимости.

1С-Битрикс и PHP - comments

En
1с битрикс php (php)