Работа с PHP при создании решений на 1С-Битрикс
Основы работы с 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 и именем.
Примечание: во всех примерах используйте исключительно классы и функции ядра Битрикс для совместимости.