CakePHP: Manual/Developing/Components/Creating

Создание компонентов

Предположим, что наша онлайн программа должна выполнять комплекс математических действий в различных частях приложения. Мы можем создать компонент, который позволит использовать наш код в разных контроллерах.

Первый шаг – это создать новый файл и класс компонента. Создадим файл в /app/controllers/components/math.php. Базовая структура для компонента будет выглядеть примерно так:

<?php

class MathComponent extends Object {

    function doComplexOperation($amount1$amount2) {

        return $amount1 $amount2;

    }

}

?>


Подключение компонентов в контроллеры

После того, как наш компонент создан, мы можем использовать его в контроллерах приложения, разместив имя компонента (без слова “Component”) в массив контроллера $components.

<?php

/* Сделайте новый компонент доступным через $this->Math,

так же как и стандартный $this->Session */

var $components = array('Math''Session');

?>

Компоненты, определенные в AppController, будут доступны в других контроллерах. Так что, нет необходимости переопределять один и тот же компонент дважды.

Когда подключаете компоненты в контроллер, вы также можете определить множество параметров, которые будут передаваться в метод компонента initialize(). Эти параметры в дальнейшем могут использоваться компонентом.

<?

var $components = array(

    'Math' => array(

        'precision' => 2,

        'randomGenerator' => 'srand'

    ),

    'Session''Auth'

);

?>

Код, приведенный выше, передаст массив, содержащий precision и randomGenerator в метод initialize() компонента MathComponent вторым параметром.


Доступ к MVC классу с помощью компонентов

Для получения доступа к экземпляру контроллера с помощью созданного компонента, вам необходимо использовать метод initialize() или startup(). Эти специальные функции принимают ссылку к контроллеру в качестве своего первого параметра и автоматически вызываются. Метод initialize() вызывается перед методом контроллера beforeFilter(), а startup() метод – после beforeFilter(). Если, по каким-то причинам, вы не хотите, чтобы startup() метод вызывался, то присвойте переменной класса $disableStartup значение true.

Если вы хотите вставить какой-то код перед тем, как beforeFilter() вызовется, вам необходимо использовать метод компонента initialize().

<?php

class CheckComponent extends Object {

    //вызывается перед Controller::beforeFilter()

    function initialize(&$controller) {

        // сохранение ссылки на контроллер для последующего использования

        $this->controller =& $controller;

    }

    //вызывается после Controller::beforeFilter()

    function startup(&$controller) {

    }

    function redirectSomewhere($value) {

        // вызов метода контроллера

        $this->controller->redirect($value);

    }

}

?>

Вы можете захотеть использовать другие компоненты внутри вашего компонента. Для этого создайте переменную класса $components в виде массива, который содержит имена нужных вам компонентов.

Только метод initialize вызывается автоматически для вложенных компонентов!

<?php

class MyComponent extends Object {

    // Этот компонент использует другие компоненты

    var $components = array('Session''Math');

    function doStuff() {

        $result $this->Math->doComplexOperation(12);

        $this->Session->write('stuff'$result);

    }

}

?>

Использовать модели в компонентах, в общем случае, не рекомендуется; однако, если после взвешивания всех возможностей, вы захотите это сделать, то вам необходимо инициализировать класс модели в какую-либо переменную и использовать ее.

Вот пример:

<?php

class MathComponent extends Object {

    function doComplexOperation($amount1$amount2) {

        return $amount1 $amount2;

    }

    function doUberComplexOperation ($amount1$amount2) {

        $userInstance ClassRegistry::init('User');

        $totalUsers $userInstance->find('count');

        return ($amount1 $amount2) / $totalUsers;

    }

}

?>


Использование других компонентов в вашем компоненте

Иногда один из ваших компонентов может зависеть от другого. Если функциональность этих компонентов не связана иначе, кроме этой зависимости, то вы не захотите объединить их в один компонент. Вместо этого вы можете сделать ваш компонент родителем, создав массив $components со списком потомков. Компоненты-родители загружаются перед их потомками и у потомков есть доступ к родителям.

Родитель:

<?php

class ParentComponent extends Object {

    var $name "Parent";

    var $components = array( "Child" );

    function initialize(&$controller) {

        $this->Child->foo();

    }

    function bar() {

        // ...

    }

}

Потомок:

<?php

class ChildComponent extends Object {

    var $name "Child";

    function initialize(&$controller) {

        $this->Parent->bar();

    }

    function foo() {

        // ...

    }

}

<< Настройка | Модели >>