Дата последнего изменения: 25.09.2024
Зайцев Артемий: Сейчас думаю, что большие компоненты - это зло, даже с классами. Выношу классы в отдельные файлы и автолоадом подключаю. Но бывает так, что нужна в компоненте пара функций. И тогда такой класс будет очень полезным. А еще статические переменные в классе. Проектировалось именно с прицелом на это. Тяжелую бизнес логику лучше держать в такой сущности как "модуль". |
Поддержка классов компонентов реализована в виде файла /component_name/class.php. Имя class.php - зарезервированно. Этот файл автоматически подключается при вызове:
$APPLICATION->IncludeComponent()
При этом происходит вызов final метода initComponent в котором и подключается class.php (если он есть) и из него берется самый последний класс наследник от CBitrixComponent.
Действия вида:
class CDemoTest extends CBitrixComponent{}
class CDemoTestDecorator1 extends CDemoTest {}
class CDemoTestDecorator2 extends CDemoTest {}
не будут иметь успеха. В итоге будет использоваться CDemoTestDecorator2.
Учтите что при изменении базового класса компонента нужно будет учитывать поведение всех его потомков (других компонентов).
Рассмотрим простейший компонент возводящий параметр в квадрат.
Файл /bitrix/components/demo/sqr/component.php:
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();
$arParams["X"] = intval($arParams["X"]);
if($this->startResultCache()) //startResultCache используется не для кеширования html, а для кеширования arResult
{
$arResult["Y"] = $arParams["X"] * $arParams["X"];
}
$this->includeComponentTemplate();
?>
Файл /bitrix/components/demo/sqr/templates/.default/template.php:
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>
<div class="equation">
<?echo $arParams["X"];?> в квадрате равно <?echo $arResult["Y"];?>
</div>
В реальных компонентах вместо операции умножения может быть три десятка строк и таких операций может быть 5-6. В результате файл component.php превращается в тяжело понимаемую "вещь в себе".
Выделяем логику компонента в класс.
Файл /bitrix/components/demo/sqr/class.php:
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();
class CDemoSqr extends CBitrixComponent
{
// Подготавливаем параметры компонента
public function onPrepareComponentParams($arParams)
{
$result = array(
"CACHE_TYPE" => $arParams["CACHE_TYPE"],
"CACHE_TIME" => isset($arParams["CACHE_TIME"]) ?$arParams["CACHE_TIME"]: 36000000,
"X" => intval($arParams["X"]),
);
return $result;
}
public function sqr($x)
{
return $x * $x;
}
}?>
Файл /bitrix/components/demo/sqr/component.php:
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();
if($this->startResultCache())//startResultCache используется не для кеширования html, а для кеширования arResult
{
//$this - экземпляр CDemoSqr
$arResult["Y"] = $this->sqr($arParams["X"]);
}
$this->includeComponentTemplate();
?>
Теперь код в файле component.php стал управляемым.
Например:
Файл /bitrix/components/demo/double_sqr/class.php:
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();
//Необходимо для корректного поиска класса CDemoSqr
CBitrixComponent::includeComponentClass("demo:sqr");
//Наследник расширяющий функциональность:
class CDemoDoubleSqr extends CDemoSqr
{
public function sqr($x)
{
return parent::sqr($x)*2;
}
}?>
Файл /bitrix/components/demo/double_sqr/component.php идентичен файлу /bitrix/components/demo/sqr/component.php, можно просто скопировать содержание.
Файл /bitrix/components/demo/double_sqr/templates/.default/template.php:
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>
<div class="equation">
<?echo $arParams["X"];?> в квадрате умноженное на два равно <?echo $arResult["Y"];?>
</div>
Создать компонент можно и без файла component.php
Для этого достаточно перекрыть метод executeComponent. Например:
class CDemoSqr extends CBitrixComponent
{
...
public function executeComponent()
{
if($this->startResultCache())
{
$this->arResult["Y"] = $this->sqr($this->arParams["X"]);
$this->includeComponentTemplate();
}
return $this->arResult["Y"];
}
};
Теперь из обоих компонентов можно удалить файлы component.php.
Обратите внимание, что глобальные переменные недоступны в методе executeComponent() в файле class.php, в отличие от файла component.php. Добавьте строку global $APPLICATION;, чтобы использовать глобальные переменные. Например:
global $APPLICATION;
// теперь можно вызвать глобальную переменную
$APPLICATION->SetTitle('header');