180  /  381

Теория. Классы компонентов

Просмотров: 45266
Дата последнего изменения: 24.10.2020
Роберт Басыров
Сложность урока:
3 уровень - средняя сложность. Необходимо внимание и немного подумать.
1
2
3
4
5
Недоступно в редакциях:
Ограничений нет

Поддержка классов

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

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

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

Поддержка классов компонентов реализована в виде файла /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
{
    //Родительский метод проходит по всем параметрам переданным в $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())//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

Можно создать и компонент без файла component.php

Для этого достаточно перекрыть метод executeComponent. Например:

class CDemoSqr extends CBitrixComponent
{
...
    public function executeComponent()
    {
        if($this->startResultCache())//startResultCache используется не для кеширования html, а для кеширования arResult
        {
            $this->arResult["Y"] = $this->sqr($this->arParams["X"]);
            $this->includeComponentTemplate();
        }
        return $this->arResult["Y"];
    }
};

Теперь из обоих компонентов можно удалить файлы component.php.


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

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