Defining behavior
To define the behavior, create a class by inheriting Yii\base\behavior or its subclasses. Such as:
namespace App\components;
Use Yii\base\behavior;
Class Mybehavior extends Behavior
{public
$prop 1;
Private $_PROP2;
Public Function GetProp2 ()
{return
$this->_prop2;
}
Public Function SetProp2 ($value)
{
$this->_prop2 = $value;
}
Public Function foo ()
{
//...
}
}
The code above defines the behavior class App\components\mybehavior and provides two properties Prop1, Prop2, and a method foo () for the component to attach the behavior. Note that property PROP2 is defined by Getter GetProp2 () and setter SetProp2 (). This can be done because Yii\base\object is the ancestor class of Yii\base\behavior, which supports defining attributes with getter and setter methods
Tip: Within the behavior, you can access the component that the behavior has attached through the Yii\base\behavior::owner property.
static method binding Behavior
Static binding behavior, only need to overload yii\base\component::behaviors () on it. This method is used to describe the behavior of the class. How do you describe it? Use configuration to describe, either the behavior class name or the configuration array of the behavior class:
namespace App\models;
Use Yii\db\activerecord;
Use App\components\mybehavior;
Class User extends ActiveRecord
{public
function behaviors ()
{return
[
//anonymous behavior, directly giving the name of the behavior
mybehavior::classname (),
//MyBehavior2 behavior, is also given the behavior of the class name
' MyBehavior2 ' => mybehavior::classname (),
//anonymous behavior, gives the configuration array of the Mybehavior class
[
' class ' => mybehavior::classname (),
' Prop1 ' => ' value1 ' ,
' prop3 ' => ' value3 ',
], the
behavior named MyBehavior4, also gives the Mybehavior class configuration array
' MyBehavior4 ' => [
' class ' => mybehavior::classname (),
' Prop1 ' => ' value1 ', ' prop3 ' => ' value3 '
,
]
;
}
}
There is also a static binding method that is bound by a configuration file:
[
' as MyBehavior2 ' => mybehavior::classname (),
' as MyBehavior3 ' => [
' class ' => Mybehavior:: ClassName (),
' Prop1 ' => ' value1 ',
' prop3 ' => ' value3 ',
],
]
Dynamic Method Binding behavior
Dynamic binding behavior, you need to invoke Yii\base\compoent::attachbehaviors ():
$Component->attachbehaviors ([
' MyBehavior1 ' => new Mybehavior,//This is a naming act
mybehavior::classname (), //This is an anonymous behavior
]);
This method takes an array argument, and the meaning of the parameter is the same as the static binding behavior above.
In these examples, an array of keys is used as the name of the behavior, and for an action that does not provide a key name, it is an anonymous behavior.
For a named behavior, you can call Yii\base\component::getbehavior () to get the bound behavior:
$behavior = $Component->getbehavior (' MyBehavior2 ');
For anonymous behavior, there is no way to directly refer to it. However, you can get all of the bound behaviors:
$behaviors = $Component->getbehaviors ();
Internal principle of binding
Just overload a yii\base\component::behaviors () so you can use the behavior so magically? This is just the tip of the iceberg, which is actually related to the process of binding:
Yii\base\component::behaviors ()
yii\base\component::ensurebehaviors ()
yii\base\component:: Attachbehaviorinternal ()
Yii\base\behavior::attach ()
Of the 4 methods, behavior is the only one, and more code is done in component.
Yii\base\component::behaviors () refers to the static method binding behavior mentioned above, that is, to return an array to describe the behavior. So what about Yii\base\component::ensuerbehaviors ()?
Off () and so on, see so much is not a headache? It's not complicated, in a word, as long as it involves the properties, methods, and events of the class, this function will be called.
So Starium, what are the ensurebehaviors () who are needed by many mortals? As the name suggests, his role is "ensure". It's just to make sure that the behavior described in behaviors () has been bound:
The Public Function ensurebehaviors ()
{
//IS NULL to indicate that it has not been bound//to
say a word, an empty array means that there is no binding to any behavior
if ($this->_behaviors = = = null) {
$this->_behaviors = [];
Iterates through the array returned by $this->behaviors () and binds
foreach ($this->behaviors () as $name => $behavior) {
$this-> Attachbehaviorinternal ($name, $behavior);
}
}
This method is mainly used for subclasses, and Yii\base\compoent does not have any pre injected behavior, so this call is not used. But for subclasses, you might overload the Yii\base\compoent::behaviros () to inject some behavior beforehand. So, this function injects these behaviors first.
From the above code, naturally saw the next to say the third Dongdong, Yii\base\component\attachbehaviorinternal ():
Private Function Attachbehaviorinternal ($name, $behavior)
{
//Not behavior instance, said to be just class name, configuration array, then create it out
if (!) ( $behavior instanceof Behavior)) {
$behavior = Yii::createobject ($behavior);
}
Anonymous behavior
if (Is_int ($name)) {
$behavior->attach ($this);
$this->_behaviors[] = $behavior;
Named Behavior
} else {
//There is already an action with the same name that you want to remove first and then bind the new behavior up.
if (isset ($this->_behaviors[$name]) {
$this->_behaviors[$name]->detach ();
}
$behavior->attach ($this);
$this->_behaviors[$name] = $behavior;
}
return $behavior;
}
The first thing to note is that this is a private member. In Yii, however, all suffixes are *internal and are private. This method has done so several things:
If the $behavior parameter is not a behavior instance, it is created as an argument, with Yii::createobject ().
If you bind the behavior in the form of an anonymous behavior, attach the behavior directly to the class.
If it is a naming act, first see if the behavior of the same name is already bound to this class, and if so, replace the previous behavior with the subsequent behavior.
In Yii\base\component::attachbehaviorinternal (), Yii\base\behavior::attach () is called with a parameter of $this. Thus, it leads to the last Guy Yii\base\behavior::attach (), which is related to the binding, which is not finished before we talk about the elements of the behavior. First look at the code:
Public function Attach ($owner)
{
$this->owner = $owner;
foreach ($this->events () as $event => $handler) {
$owner->on ($event, is_string ($handler)? [$this, $handler]:
$handler);
}
The code above has done two things:
- Set the $owner of good behavior so that the behavior can be accessed and manipulated by the object to which it is attached
- An array of events () returned in the traversal behavior, the event to be prepared to respond, bound to the class by the on () of the dependent class
Summarize
Say so much about binding, make a summary:
The
- -bound action is initiated from component, and the
- static binding is implemented by overloading Yii\base\componet::behaviors ();
- dynamic binding by calling Yii\base\componen T::attachbehaviors () Implementation, the
- behavior can also be bound by configuring the As configuration item for Component, and
- behavior is distinguished by anonymous behavior and naming behavior, whether or not a name is given when binding. The naming behavior can be identified by its name, so that the action is targeted to be lifted; the behavior of the subsequent binding replaces the behavior of the same name that has already been bound during the
- binding, and the
- binding has two points and the first is set $owner for the behavior. The second is to bind the handler of the event in action to the class.