160  /  331

Поддержка классов компонентов

Просмотров: 8623 (Статистика ведётся с 06.02.2017)
Дата последнего изменения: 17.09.2015
Зайцев Артемий:
Сейчас думаю, что большие компоненты - это зло, даже с классами. Выношу классы в отдельные файлы и автолоадом подключаю.
Но бывает так, что нужна в компоненте пара функций. И тогда такой класс будет очень полезным. А еще статические переменные в классе.

Максим Смирнов:

Проектировалось именно с прицелом на это.
Тяжелую бизнес логику лучше держать в такой сущности как "модуль".

С версии 12.0.0 доступна поддержка классов компонентов. Реализовано это в виде файла /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())
{
    $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
{
    //Родительский метод проходит по всем параметрам переданным в $APPLICATION->IncludeComponent
    //и применяет к ним функцию htmlspecialcharsex. В данном случае такая обработка избыточна.
    //Переопределяем.
    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())
{
    //$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

Можно создать и компонент без файла 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.


59
Курсы разработаны в компании «1С-Битрикс»

Если вы нашли неточность в тексте, непонятное объяснение, пожалуйста, сообщите нам об этом в комментариях.
Развернуть комментарии