diff --git a/docs/guide-ru/concept-behaviors.md b/docs/guide-ru/concept-behaviors.md index f9d3093..e1c7c9d 100644 --- a/docs/guide-ru/concept-behaviors.md +++ b/docs/guide-ru/concept-behaviors.md @@ -1,68 +1,116 @@ Поведения ========= -Поведения (behaviors) - это экземпляры класса [[yii\base\Behavior]] или класса, унаследованного от него. Поведения, +Поведения (behaviors) — это экземпляры класса [[yii\base\Behavior]] или класса, унаследованного от него. Поведения, также известные как [примеси](http://ru.wikipedia.org/wiki/Примесь_(программирование)), позволяют расширять -функциональность существующих [[yii\base\Component|компонентов]] без необходимости их изменения. +функциональность существующих [[yii\base\Component|компонентов]] без необходимости изменения дерева наследования. После прикрепления поведения к компоненту, его методы и свойства "внедряются" в компонент, и становятся доступными так же, как если бы они были объявлены в самом классе компонента. Кроме того, поведение может реагировать на [события](concept-events.md), создаваемые компонентом, что позволяет тонко настраивать или модифицировать обычное выполнение кода компонента. -Использование Поведений <a name="using-behaviors"></a> ---------------- +Создание поведений <a name="defining-behaviors"></a> +---------------------------------------------- -Для использования поведения, его необходимо прикрепить к [[yii\base\Component|компоненту]]. Подробнее о том, как -это сделать, описано в следующем разделе. +Поведения создаются путем расширения базового класса [[yii\base\Behavior]] или его наследников. Например, -После того, как поведение прикреплено к компоненту, его использование не вызывает сложностей. +```php +namespace app\components; -Вы можете обращаться к *публичным* переменным или [свойствам](concept-properties.md), объявленным с использованием -геттеров и сеттеров в поведении, через компонент, к которому оно прикреплено, как показано ниже, +use yii\base\Behavior; -```php -// публичное свойство "prop1" объявленное в классе поведения -echo $component->prop1; -$component->prop1 = $value; -``` +class MyBehavior extends Behavior +{ + public $prop1; -Аналогично, вы можете вызывать *публичные* методы поведения, + private $_prop2; -```php -// публичный метод bar() объявленный в классе поведения -$component->bar(); + public function getProp2() + { + return $this->_prop2; + } + + public function setProp2($value) + { + $this->_prop2 = $value; + } + + public function foo() + { + // ... + } +} ``` -Обратите внимание, хотя `$component` не имеет свойства `prop1` и метода `bar()`, они могут быть использованы, -как будто являются членами этого класса. +В приведенном выше примере, объявлен класс поведения `app\components\MyBehavior` содержащий 2 свойства +`prop1` и `prop2`, и один метод `foo()`. Обратите внимание, свойство `prop2` объявлено с использованием геттера +`getProp2()` и сеттера `setProp2()`. Это возможно, так как [[yii\base\Behavior]] является дочерним классом для +[[yii\base\Object]], который предоставляет возможность определения [свойств](concept-properties.md) через геттеры и сеттеры. -В случае, когда два поведения, имеющие свойства или методы с одинаковыми именами, прикреплены к одному компоненту, -преимущество будет у поведения, прикрепленного раньше. +Так как этот класс является поведением, когда он прикреплён к компоненту, компоненту будут также доступны свойства `prop1` +и `prop2`, а также метод `foo()`. + +> Подсказка: Внутри поведения возможно обращаться к компоненту, к которому оно прикреплено, используя свойство + [[yii\base\Behavior::owner]]. + + +Обработка событий компонента +------------------------- -Поведение может быть связано (associated) по имени по время прикрепления к компоненту. Это предоставляет возможность, -обращаться к поведению по его имени, как показано ниже, +Если поведению требуется реагировать на события компонента, к которому оно прикреплено, то необходимо переопределить +метод [[yii\base\Behavior::events()]]. Например, ```php -$behavior = $component->getBehavior('myBehavior'); +namespace app\components; + +use yii\db\ActiveRecord; +use yii\base\Behavior; + +class MyBehavior extends Behavior +{ + // ... + + public function events() + { + return [ + ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValidate', + ]; + } + + public function beforeValidate($event) + { + // ... + } +} ``` -Также можно получить все поведения, прикрепленные к компоненту: +Метод [[yii\base\Behavior::events()|events()]] должен возвращать список событий и соответствующих им обработчиков. +В приведенном выше примере, объявлено событие [[yii\db\ActiveRecord::EVENT_BEFORE_VALIDATE|EVENT_BEFORE_VALIDATE]] +и его обработчик `beforeValidate()`. Указать обработчик события, можно одним из следующих способов: + +* строка с именем метода текущего поведения, как в примере выше; +* массив, содержащий объект или имя класса, и имя метода, например, `[$object, 'methodName']`; +* анонимная функция. +Функция обработчика события должна выглядеть как показано ниже, где `$event` содержит параметр +события. Более детальная информация приведена в разделе [События](concept-events.md). ```php -$behaviors = $component->getBehaviors(); +function ($event) { +} ``` +Прикрепление поведений <a name="attaching-behaviors"></a> +--------------------------------------------------- -Прикрепление Поведений <a name="attaching-behaviors"></a> -------------------- - -Прикрепить поведение к [[yii\base\Component|компоненту]] можно статически (statically) или динамически (dynamically). -На практике, чаще используется статическое прикрепление. +Прикрепить поведение к [[yii\base\Component|компоненту]] можно как статически, так и динамически. На практике +чаще используется статическое прикрепление. -Для того чтобы прикрепить поведение статически, необходимо переопределить метод -[[yii\base\Component::behaviors()|behaviors()]] класса компонента. Например, +Для того чтобы прикрепить поведение статически, необходимо переопределить метод [[yii\base\Component::behaviors()|behaviors()]] +компонента, к которому его планируется прикрепить. Метод [[yii\base\Component::behaviors()|behaviors()]] должен возвращать +список [конфигураций](concept-configurations.md) поведений. Конфигурация поведения представляет собой имя класса поведения, +либо массив его настроек: ```php namespace app\models; @@ -99,17 +147,13 @@ class User extends ActiveRecord } ``` -Метод [[yii\base\Component::behaviors()|behaviors()]] должен возвращать список -[конфигураций](concept-configurations.md) поведений. Конфигурация поведения представляет собой имя класса поведения, -либо массив его настроек. - Вы можете связать имя с поведением, указав его в качестве ключа элемента массива, соответствующего конфигурации -поведения. В таком случае, поведение называется *именованным поведением (named behavior)*. В примере выше, -два именованных поведения: `myBehavior2` и `myBehavior4`. Если с поведением не связано имя, такое поведение называется -*анонимным поведением (anonymous behavior)*. +поведения. В таком случае, поведение называется *именованным*. В примере выше, +два именованных поведения: `myBehavior2` и `myBehavior4`. Если с поведением не связано имя, такое поведение называется +*анонимным*. -Для того, чтобы прикрепить поведение динамически, необходимо вызвать метод [[yii\base\Component::attachBehavior()]] -требуемого компонента. Например, +Для того, чтобы прикрепить поведение динамически, необходимо вызвать метод [[yii\base\Component::attachBehavior()]] +требуемого компонента: ```php use app\components\MyBehavior; @@ -138,8 +182,7 @@ $component->attachBehaviors([ ]); ``` -Так же, прикрепить поведение к компоненту можно через [конфигурацию](concept-configurations.md), как показано ниже. -Более детальная информация приведена в разделе [Конфигурации](concept-configurations.md#configuration-format). +Так же, прикрепить поведение к компоненту можно через [конфигурацию](concept-configurations.md), как показано ниже: ```php [ @@ -153,117 +196,72 @@ $component->attachBehaviors([ ] ``` +Более детальная информация приведена в разделе [Конфигурации](concept-configurations.md#configuration-format). -Отвязывание Поведений<a name="detaching-behaviors"></a> -------------------- +Использование поведений <a name="using-behaviors"></a> +------------------------------------------------ -Чтобы отвязать (detach) поведение, необходимо вызвать метод [[yii\base\Component::detachBehavior()]], указав имя, -связанное с поведением: +Для использования поведения, его необходимо прикрепить к [[yii\base\Component|компоненту]] как описано выше. После того, +как поведение прикреплено к компоненту, его использование не вызывает сложностей. + +Вы можете обращаться к *публичным* переменным или [свойствам](concept-properties.md), объявленным с использованием +геттеров и сеттеров в поведении, через компонент, к которому оно прикреплено: ```php -$component->detachBehavior('myBehavior1'); +// публичное свойство "prop1" объявленное в классе поведения +echo $component->prop1; +$component->prop1 = $value; ``` -Так же, возможно отвязать *все* поведения: +Аналогично, вы можете вызывать *публичные* методы поведения, ```php -$component->detachBehaviors(); +// публичный метод bar() объявленный в классе поведения +$component->bar(); ``` +Обратите внимание, хотя `$component` не имеет свойства `prop1` и метода `bar()`, они могут быть использованы, +как будто являются членами этого класса. -Создание Поведений <a name="defining-behaviors"></a> ------------------- +В случае, когда два поведения, имеющие свойства или методы с одинаковыми именами, прикреплены к одному компоненту, +преимущество будет у поведения, прикрепленного раньше. -Поведения создаются путем расширения базового класса [[yii\base\Behavior]] или его наследников. Например, +Если при прикреплении поведения к компоненту указано имя, можно обращаться к поведению по этому имени, как показано ниже: ```php -namespace app\components; - -use yii\base\Model; -use yii\base\Behavior; - -class MyBehavior extends Behavior -{ - public $prop1; - - private $_prop2; - - public function getProp2() - { - return $this->_prop2; - } - - public function setProp2($value) - { - $this->_prop2 = $value; - } - - public function foo() - { - // ... - } -} +$behavior = $component->getBehavior('myBehavior'); ``` -В приведенном выше примере, объявлен класс поведения `app\components\MyBehavior` содержащий 2 свойства -`prop1` и `prop2`, и один метод `foo()`, которые будут доступны компоненту, к которому оно прикреплено. -Обратите внимание, свойство `prop2` объявлено с использованием геттера `getProp2()` и сеттера`setProp2()`. -Это возможно, так как [[yii\base\Behavior]] является дочерним классом для [[yii\base\Object]], который предоставляет -возможность определения [свойств](concept-properties.md) через геттеры и сеттеры. - -Внутри поведения возможно обращаться к свойствам компонента, к которому оно прикреплено, используя свойство -[[yii\base\Behavior::owner]]. -Если поведению требуется реагировать на события компонента, к которому оно прикреплено, то необходимо переопределить -метод [[yii\base\Behavior::events()]]. Например, +Также можно получить все поведения, прикрепленные к компоненту: ```php -namespace app\components; - -use yii\db\ActiveRecord; -use yii\base\Behavior; +$behaviors = $component->getBehaviors(); +``` -class MyBehavior extends Behavior -{ - // ... +Отвязывание поведений<a name="detaching-behaviors"></a> +------------------------------------------------- - public function events() - { - return [ - ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValidate', - ]; - } +Чтобы отвязать поведение от компонента, необходимо вызвать метод [[yii\base\Component::detachBehavior()]], указав имя, +связанное с поведением: - public function beforeValidate($event) - { - // ... - } -} +```php +$component->detachBehavior('myBehavior1'); ``` -Метод [[yii\base\Behavior::events()|events()]] должен возвращать список событий и соответствующих им обработчиков. -В приведенном выше примере, объявлено событие [[yii\db\ActiveRecord::EVENT_BEFORE_VALIDATE|EVENT_BEFORE_VALIDATE]] -и его обработчик `beforeValidate()`. Указать обработчик события, можно одним из следующих способов: - -* строка с именем метода текущего поведения, как в примере выше; -* массив, содержащий объект или имя класса, и имя метода, например, `[$object, 'methodName']`; -* анонимная функция. - -Сигнатура (signature) функции обработчика события должна выглядеть как показано ниже, где `$event` содержит параметр -события. Более детальная информация приведена в разделе [События](concept-events.md). +Так же, возможно отвязать *все* поведения: ```php -function ($event) { -} +$component->detachBehaviors(); ``` Использование поведения `TimestampBehavior` <a name="using-timestamp-behavior"></a> -------------------------- +-------------------------------------------------------------------------- -В заключении, давайте посмотрим на [[yii\behaviors\TimestampBehavior]] - поведение, которое позволяет автоматически +В заключении, давайте посмотрим на [[yii\behaviors\TimestampBehavior]] — поведение, которое позволяет автоматически обновлять атрибуты с метками времени при сохранении [[yii\db\ActiveRecord|Active Record]] моделей. -Для начала, необходимо прикрепить поведение к классу [[yii\db\ActiveRecord|Active Record]], в котором это необходимо. +Для начала, необходимо прикрепить поведение к классу [[yii\db\ActiveRecord|Active Record]], в котором это необходимо: ```php namespace app\models\User; @@ -292,10 +290,8 @@ class User extends ActiveRecord Конфигурация выше описывает следующее: -* когда будет добавлена новая запись (insert), поведение должно присвоить текущую метку времени (timestamp) атрибутам - `created_at` и `updated_at`; -* когда будет обновлена существующая запись (update), поведение должно присвоить текущую метку времени атрибуту - `updated_at`. +* при вставке новой записи поведение должно присвоить текущую метку времени атрибутам `created_at` и `updated_at`; +* при обновлении существующей записи поведение должно присвоить текущую метку времени атрибуту `updated_at`. Теперь, если сохранить объект `User`, то в его атрибуты `created_at` и `updated_at` будут автоматически установлены значения метки времени на момент сохранения записи: @@ -304,7 +300,7 @@ class User extends ActiveRecord $user = new User; $user->email = 'test@example.com'; $user->save(); -echo $user->created_at; // отобразить метку времени на момент сохранения записи +echo $user->created_at; // выведет метку времени на момент сохранения записи ``` Поведение [[yii\behaviors\TimestampBehavior|TimestampBehavior]] так же содержит полезный метод @@ -316,23 +312,23 @@ $user->touch('login_time'); ``` -Сравнение с Трейтами <a name="comparison-with-traits"></a> ----------------------- +Сравнение с трейтами <a name="comparison-with-traits"></a> +--------------------------------------------------- Несмотря на то, что поведения схожи с [трейтами](http://ru2.php.net/manual/ru/language.oop5.traits.php) тем, что "внедряют" свои свойства и методы в основной класс, они имеют множество отличий. Они оба имеют свои плюсы и минусы, и, скорее, дополняют друг друга, а не заменяют. -### Плюсы Поведений <a name="pros-for-behaviors"></a> +### Плюсы поведений <a name="pros-for-behaviors"></a> -Поведения, как и любые другие классы, поддерживают наследование. Трейты можно рассматривать как копипейст -на уровне языка. Они не поддерживают наследование. +Поведения, как и любые другие классы, поддерживают наследование. Трейты же можно рассматривать как копипейст +на уровне языка. Они наследование не поддерживают. Поведения могут быть прикреплены и отвязаны от компонента динамически, без необходимости модифицирования класса -компонента. Для использование Трейтов необходимо модифицировать класс. +компонента. Для использование трейтов необходимо модифицировать класс. -Поведения, в отличии от трейтов, можно настраивать. +Поведения, в отличие от трейтов, можно настраивать. Поведения можно настраивать таким образом, чтобы они реагировали на события компонента. @@ -340,7 +336,7 @@ $user->touch('login_time'); Конфликты имен, вызванные различными трейтами, требуют ручного переименования конфликтующих свойств или методов. -### Плюсы Трейтов <a name="pros-for-traits"></a> +### Плюсы трейтов <a name="pros-for-traits"></a> Трейты являются гораздо более производительными, чем поведения поведений, которые, являясь объектами, требуют дополнительного времени и памяти.