
Внутри поведения можно обращаться к компоненту, к которому оно прикреплено, используя свойство yii\base\Behavior::$owner:
$this->owner //PostController Object
Есть такие способы задать нужное поведение классу:
- Привязка на уровне объекта (контроллер, модель, компонент…) – переопределение метода behaviors();
- Динамическая привязка (из методов/действий) не переопределяя метод behaviors();
- Привязка через конфигурацию.
Привязка на уровне объекта
Если вы делаете отдельный класс, то он расширяет модель, те публичные методы этого класса становятся доступными из модели. Так же в классе можно прописать срабатывание поведений на событие.Пример.
class PostController extends Controller { public function behaviors() { return [ 'slug' => [ 'class' => 'common\behaviors\Slug', //класс для поведения 'iniciali' => 'post_', //переменная для класса ] ]; } …в контроллере создается поведение которое вызывается до выполнения действий.
'slug' – название массива данных, может быть любым, в т.ч. не совпадать с названием класса или вообще отсутствовать. В данном случае, поведение называется именованным.
'class' – указывается вызываемый класс.
'iniciali' – публичная переменная которая передает данные в класс. Т.к. данный класс Slug может вызываться для разных контроллеров, моделей… могут передаваться разные значения переменных.
Если не нужно передавать данные в класс, то можно написать более кратко и без названия (анонимное поведение):
public function behaviors() { return [ \common\behaviors\Slug::className(), ...
Класс поведения может выглядеть так:
<?php namespace common\behaviors; use yii; use yii\base\Behavior; class Slug extends Behavior { public $iniciali = null; public function events() { return [ yii\web\Controller::EVENT_BEFORE_ACTION => 'getMyMetod' ]; } public function getMyMetod(){ yii::$app->params['fio'] = $this->iniciali . "ksl"; } }В данном случае поведение используется для привязки события к действию контроллера. А именно - перед выполнением любого действия данного контроллера выполнится метод getMyMetod() из класса поведения.
yii\web\Controller – указывается к чему привязываем
EVENT_BEFORE_ACTION – событие которое должно сработать (см.список стандартных событий тут)
getMyMetod – название метода класса, который вызовется при наступлении события.
В нашем поведении создается глобальный параметр приложения 'fio' со значением post_ksl перед вызовом любого действия. Получить значение можно так:
public function actionIndex() { exit(\yii::$app->params['fio']); …
Кроме использования событий, методы класса указанного в поведении расширяют объект в котором это поведение определено (контроллер, модель…)
То есть если добавить в class Slug метод
public function name(){ return 'Сергей'; }
Его можно будет вызвать в действиях контроллера:
$this->name()
Динамическая привязка (из методов/действий) не переопределяя метод behaviors().
Для того, чтобы прикрепить поведение динамически, необходимо вызвать метод yii\base\Component::attachBehavior() требуемого компонента.
Первым параметром указывается произвольное название поведения.
use app\components\MyBehavior; // прикрепляем объект поведения $component->attachBehavior('myBehavior1', new MyBehavior); // прикрепляем по имени класса поведения $component->attachBehavior('myBehavior2', MyBehavior::className()); // прикрепляем используя массив конфигураций $component->attachBehavior('myBehavior3', [ 'class' => MyBehavior::className(), 'prop1' => 'value1', 'prop2' => 'value2', ]);
Пример привязки класса Slug к Controller
yii\web\Controller::attachBehavior('Slug','common\behaviors\Slug'); //или тоже самое yii\web\Controller::attachBehavior('Slug', \common\behaviors\Slug::className()); //если указывается для текущего объекта: $this->attachBehavior('Slug', 'common\behaviors\Slug') //с передачей параметров: $this->attachBehavior('Slug', [ 'class' => '\common\behaviors\Slug', 'iniciali' => 'ksl', ]);Так же можно подключить сразу несколько поведений:
$component->attachBehaviors([ 'myBehavior1' => new MyBehavior, // именованное поведение MyBehavior::className(), // анонимное поведение ]);
Привязка через конфигурацию
Если вы подключаете свои компоненты в файле \config\main.php, то привязать поведение можно сразу при подключении.Делается это с помощью приставки «as », после чего следует название поведения.
'comp' => [ 'class' => 'common\components\Comp', 'age' => 23, 'as Slug' => [ 'class' => 'common\behaviors\Slug', 'iniciali' => 'ksl', ], ],Ваш компонент должен наследоваться от класса yii\base\Component или его наследника, а класс поведения от yii\base\Behavior.
После этого при вызове компонента – класса Comp будут доступны методы и из поведения (класс Slug).
Например:
Yii::$app->comp->name()
Можно привязать поведения для самого объекта приложения($app):
В config\main.php одним из элементов массива в return:
return [ 'params' => $params, … 'as Slug' => [ 'class' => 'common\behaviors\Slug', 'iniciali' => 'ksl', //параметр для переменной класса ],
После этого в приложение добавятся свойства и методы из указанного класса. Например метод name(), который можно теперь вызвать так:
Yii::$app->name()
Если не нужно передавать параметры, то можно прописать одной строкой:
'as myBehavior' => 'common\behaviors\MyBehavior',или (одно и тоже)
'as myBehavior' => MyBehavior::className(),
Call to undefined method, где то осталась неточность, проверьте
ответ на комментарий Alex от 07.05.2018
ответ на комментарий Сергей от 08.05.2018