yii2源码学习笔记(六)
Posted dragon16
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了yii2源码学习笔记(六)相关的知识,希望对你有一定的参考价值。
Behvaior类,Behavior类是所有事件类的基类:
目录yii2\base\Behavior.php
1 <?php 2 /** 3 * @link http://www.yiiframework.com/ 4 * @copyright Copyright (c) 2008 Yii Software LLC 5 * @license http://www.yiiframework.com/license/ 6 */ 7 8 namespace yii\base; 9 10 /** 11 * Behavior is the base class for all behavior classes. 12 * 所有行为的基类 13 * A behavior can be used to enhance the functionality of an existing component without modifying its code. 14 * In particular, it can "inject" its own methods and properties into the component 15 * and make them directly accessible via the component. It can also respond to the events triggered in the component 16 * and thus intercept the normal code execution. 17 * 用来增强现有组件的功能而不修改它的代码。它可以添加自己的方法和属性组件 18 * 使他们可以直接通过组件访问。还可以响应组件触发的事件,拦截正常的代码执行。 19 * @author Qiang Xue <[email protected]> 20 * @since 2.0 21 * 继承父类Object 22 */ 23 class Behavior extends Object 24 { 25 /** 26 * @var Component the owner of this behavior 要附加行为对象的组件。 27 */ 28 public $owner; 29 30 31 /** 32 * Declares event handlers for the [[owner]]‘s events. 33 * 声明[[owner]]的事件处理程序 34 * Child classes may override this method to declare what PHP callbacks should 35 * be attached to the events of the [[owner]] component. 36 * 子类可以重写此方法 php回调应连接 [[owner]]组件。 37 * The callbacks will be attached to the [[owner]]‘s events when the behavior is 38 * attached to the owner; and they will be detached from the events when 39 * the behavior is detached from the component. 40 * 当行为被连接到owner时回调将附在[[owner]]的事件中,当行为从组件中分离时,它们将被分离 41 * The callbacks can be any of the followings: 42 * 43 * - method in this behavior: `‘handleClick‘`, equivalent to `[$this, ‘handleClick‘]` 44 * - object method: `[$object, ‘handleClick‘]` 45 * - static method: `[‘Page‘, ‘handleClick‘]` 46 * - anonymous function: `function ($event) { ... }` 47 * 48 * The following is an example: 49 * 50 * ~~~ 51 * [ 52 * Model::EVENT_BEFORE_VALIDATE => ‘myBeforeValidate‘, 53 * Model::EVENT_AFTER_VALIDATE => ‘myAfterValidate‘, 54 * ] 55 * ~~~ 56 * 57 * @return array events (array keys) and the corresponding event handler methods (array values). 58 * 事件和相应的事件处理方法 59 */ 60 public function events() 61 { 62 return []; 63 } 64 65 /** 66 * Attaches the behavior object to the component.绑定行为到组件 67 * The default implementation will set the [[owner]] property 68 * and attach event handlers as declared in [[events]]. 69 * 默认设置[[owner]]属性并将事件处理程序绑定到组件 70 * Make sure you call the parent implementation if you override this method. 如果重写方法,确保调用父类去实现 71 * @param Component $owner the component that this behavior is to be attached to. 行为绑定到$owner组件 72 */ 73 public function attach($owner) 74 { 75 $this->owner = $owner;//设置 $owner ,使得所依附的对象可以访问、操作 76 foreach ($this->events() as $event => $handler) { 77 //将准备响应的事件,通过所依附类的 on()方法 绑定到类上 78 $owner->on($event, is_string($handler) ? [$this, $handler] : $handler); 79 } 80 } 81 82 /** 83 * Detaches the behavior object from the component. 解除绑定的行为 84 * The default implementation will unset the [[owner]] property 默认取消 owner的属性 85 * and detach event handlers declared in [[events]]. 将events中的事件程序解除绑定 86 * Make sure you call the parent implementation if you override this method.如果重写方法,确保调用父类去实现 87 */ 88 public function detach() 89 { 90 if ($this->owner) { 91 foreach ($this->events() as $event => $handler) {//遍历行为中 events() 返回的数组 92 //通过Component的 off() 将绑定到类上的事件解除 93 $this->owner->off($event, is_string($handler) ? [$this, $handler] : $handler); 94 } 95 $this->owner = null;//将 $owner 设置为 null ,表示这个解除绑定 96 } 97 } 98 }
接下来看一下model类,它是所有模型的基类
目录yii2\base\Model.php
1 <?php 2 /** 3 * @link http://www.yiiframework.com/ 4 * @copyright Copyright (c) 2008 Yii Software LLC 5 * @license http://www.yiiframework.com/license/ 6 */ 7 8 namespace yii\base; 9 10 use Yii; 11 use ArrayAccess; 12 use ArrayObject; 13 use ArrayIterator; 14 use ReflectionClass; 15 use IteratorAggregate; 16 use yii\helpers\Inflector; 17 use yii\validators\RequiredValidator; 18 use yii\validators\Validator; 19 20 /** 21 * Model is the base class for data models. 22 * 23 * IteratorAggregate(聚合式迭代器)接口 — 创建外部迭代器的接口, 需实现 getIterator 方法。 24 * IteratorAggregate::getIterator — 获取一个外部迭代器, foreach 会调用该方法。 25 * 26 * ArrayAccess(数组式访问)接口 — 提供像访问数组一样访问对象的能力的接口, 需实现如下方法: 27 * ArrayAccess::offsetExists — 检查一个偏移位置是否存在 28 * ArrayAccess::offsetGet — 获取一个偏移位置的值 29 * ArrayAccess::offsetSet — 设置一个偏移位置的值 30 * ArrayAccess::offsetUnset — 复位一个偏移位置的值 31 * 在 Model 中用于实现将 $model[$field] 替换为 $model->$field 32 * 33 * Model implements the following commonly used features: 34 * 35 * - attribute declaration: by default, every public class member is considered as 36 * a model attribute 37 * - attribute labels: each attribute may be associated with a label for display purpose 38 * - massive attribute assignment 39 * - scenario-based validation 40 * 41 * Model also raises the following events when performing data validation: 42 * 43 * - [[EVENT_BEFORE_VALIDATE]]: an event raised at the beginning of [[validate()]] 44 * - [[EVENT_AFTER_VALIDATE]]: an event raised at the end of [[validate()]] 45 * 46 * You may directly use Model to store model data, or extend it with customization. 47 * 48 * @property \yii\validators\Validator[] $activeValidators The validators applicable to the current 49 * [[scenario]]. This property is read-only. 50 * @property array $attributes Attribute values (name => value). 51 * @property array $errors An array of errors for all attributes. Empty array is returned if no error. The 52 * result is a two-dimensional array. See [[getErrors()]] for detailed description. This property is read-only. 53 * @property array $firstErrors The first errors. The array keys are the attribute names, and the array values 54 * are the corresponding error messages. An empty array will be returned if there is no error. This property is 55 * read-only. 56 * @property ArrayIterator $iterator An iterator for traversing the items in the list. This property is 57 * read-only. 58 * @property string $scenario The scenario that this model is in. Defaults to [[SCENARIO_DEFAULT]]. 59 * @property ArrayObject|\yii\validators\Validator[] $validators All the validators declared in the model. 60 * This property is read-only. 61 * 62 * @author Qiang Xue <[email protected]> 63 * @since 2.0 64 */ 65 class Model extends Component implements IteratorAggregate, ArrayAccess, Arrayable 66 { 67 use ArrayableTrait; 68 69 /** 70 * The name of the default scenario. 71 * 默认场景的名称 72 */ 73 const SCENARIO_DEFAULT = ‘default‘; 74 /** 75 * @event ModelEvent an event raised at the beginning of [[validate()]]. You may set 76 * [[ModelEvent::isValid]] to be false to stop the validation. 77 */ 78 const EVENT_BEFORE_VALIDATE = ‘beforeValidate‘; 79 /** 80 * @event Event an event raised at the end of [[validate()]] 81 */ 82 const EVENT_AFTER_VALIDATE = ‘afterValidate‘; 83 84 /** 85 * @var array validation errors (attribute name => array of errors) 86 * 验证的错误信息 87 */ 88 private $_errors; 89 /** 90 * @var ArrayObject list of validators 91 */ 92 private $_validators; 93 /** 94 * @var string current scenario 95 * 当前的场景,默认是default 96 */ 97 private $_scenario = self::SCENARIO_DEFAULT; 98 99 100 /** 101 * Returns the validation rules for attributes. 102 * 103 * 返回属性的验证规则 104 * 105 * Validation rules are used by [[validate()]] to check if attribute values are valid. 106 * Child classes may override this method to declare different validation rules. 107 * 108 * Each rule is an array with the following structure: 109 * 110 * ~~~ 111 * [ 112 * [‘attribute1‘, ‘attribute2‘], 113 * ‘validator type‘, 114 * ‘on‘ => [‘scenario1‘, ‘scenario2‘], 115 * ...other parameters... 116 * ] 117 * ~~~ 118 * 119 * where 120 * 121 * - attribute list: required, specifies the attributes array to be validated, for single attribute you can pass string; 122 * - validator type: required, specifies the validator to be used. It can be a built-in validator name, 123 * a method name of the model class, an anonymous function, or a validator class name. 124 * - on: optional, specifies the [[scenario|scenarios]] array when the validation 125 * rule can be applied. If this option is not set, the rule will apply to all scenarios. 126 * - additional name-value pairs can be specified to initialize the corresponding validator properties. 127 * Please refer to individual validator class API for possible properties. 128 * 129 * A validator can be either an object of a class extending [[Validator]], or a model class method 130 * (called *inline validator*) that has the following signature: 131 * 132 * ~~~ 133 * // $params refers to validation parameters given in the rule 134 * function validatorName($attribute, $params) 135 * ~~~ 136 * 137 * In the above `$attribute` refers to currently validated attribute name while `$params` contains an array of 138 * validator configuration options such as `max` in case of `string` validator. Currently validate attribute value 139 * can be accessed as `$this->[$attribute]`. 140 * 141 * Yii also provides a set of [[Validator::builtInValidators|built-in validators]]. 142 * They each has an alias name which can be used when specifying a validation rule. 143 * 144 * Below are some examples: 145 * 146 * ~~~ 147 * [ 148 * // built-in "required" validator 149 * [[‘username‘, ‘password‘], ‘required‘], 150 * // built-in "string" validator customized with "min" and "max" properties 151 * [‘username‘, ‘string‘, ‘min‘ => 3, ‘max‘ => 12], 152 * // built-in "compare" validator that is used in "register" scenario only 153 * [‘password‘, ‘compare‘, ‘compareAttribute‘ => ‘password2‘, ‘on‘ => ‘register‘], 154 * // an inline validator defined via the "authenticate()" method in the model class 155 * [‘password‘, ‘authenticate‘, ‘on‘ => ‘login‘], 156 * // a validator of class "DateRangeValidator" 157 * [‘dateRange‘, ‘DateRangeValidator‘], 158 * ]; 159 * ~~~ 160 * 161 * Note, in order to inherit rules defined in the parent class, a child class needs to 162 * merge the parent rules with child rules using functions such as `array_merge()`. 163 * 164 * @return array validation rules 165 * @see scenarios() 166 */ 167 public function rules() 168 { 169 return []; 170 } 171 172 /** 173 * Returns a list of scenarios and the corresponding active attributes. 174 * An active attribute is one that is subject to validation in the current scenario. 175 * 返回场景及与之对应的 active 属性的列表 176 * The returned array should be in the following format: 177 * 178 * ~~~ 179 * [ 180 * ‘scenario1‘ => [‘attribute11‘, ‘attribute12‘, ...], 181 * ‘scenario2‘ => [‘attribute21‘, ‘attribute22‘, ...], 182 * ... 183 * ] 184 * ~~~ 185 * 186 * By default, an active attribute is considered safe and can be massively assigned. 187 * If an attribute should NOT be massively assigned (thus considered unsafe), 188 * please prefix the attribute with an exclamation character (e.g. ‘!rank‘). 189 * 190 * The default implementation of this method will return all scenarios found in the [[rules()]] 191 * declaration. A special scenario named [[SCENARIO_DEFAULT]] will contain all attributes 192 * found in the [[rules()]]. Each scenario will be associated with the attributes that 193 * are being validated by the validation rules that apply to the scenario. 194 * 195 * @return array a list of scenarios and the corresponding active attributes. 196 */ 197 public function scenarios() 198 { 199 // 默认有 default 的场景 200 $scenarios = [self::SCENARIO_DEFAULT => []]; 201 foreach ($this->getValidators() as $validator) { 202 // 循环 validator,取出所有提到的场景,包括 on 和 except 203 foreach ($validator->on as $scenario) { 204 $scenarios[$scenario] = []; 205 } 206 foreach ($validator->except as $scenario) { 207 $scenarios[$scenario] = []; 208 } 209 } 210 // 取出所有场景的名称 211 $names = array_keys($scenarios); 212 213 foreach ($this->getValidators() as $validator) { 214 if (empty($validator->on) && empty($validator->except)) { 215 // 如果 validator 即没有定义 on,也没有定义 except,就放到所有的场景中 216 foreach ($names as $name) { 217 // 循环 $validator 的所有属性 218 foreach ($validator->attributes as $attribute) { 219 $scenarios[$name][$attribute] = true; 220 } 221 } 222 } elseif (empty($validator->on)) { 223 // 如果没有定义 on 224 foreach ($names as $name) { 225 if (!in_array($name, $validator->except, true)) { 226 // 而且场景不在 except 中, 就将这个属性加入到相应的场景中 227 foreach ($validator->attributes as $attribute) { 228 $scenarios[$name][$attribute] = true; 229 } 230 } 231 } 232 } else { 233 // 如果定义了 on 234 foreach ($validator->on as $name) { 235 // 就将这个属性加入到 on 定义的场景中 236 foreach ($validator->attributes as $attribute) { 237 $scenarios[$name][$attribute] = true; 238 } 239 } 240 } 241 } 242 243 /** 244 * 将 $scenarios 从 245 * 246 * ~~~ 247 * [ 248 * ‘default‘ => [], 249 * ‘scenario1‘ => [‘attribute11‘ => true, ‘attribute12‘ => true, ...], 250 * ‘scenario2‘ => [‘attribute21‘ => true, ‘attribute22‘ => true, ...], 251 * ‘scenario3‘ => [], 252 * ... 253 * ] 254 * ~~~ 255 * 转化为 256 * ~~~ 257 * [ 258 * ‘default‘ => [], 259 * ‘scenario1‘ => [‘attribute11‘, ‘attribute12‘, ...], 260 * ‘scenario2‘ => [‘attribute21‘, ‘attribute22‘, ...], 261 * ... 262 * ] 263 * ~~~ 264 */ 265 foreach ($scenarios as $scenario => $attributes) { 266 // 去除掉没有属性值的场景 267 if (empty($attributes) && $scenario !== self::SCENARIO_DEFAULT) { 268 unset($scenarios[$scenario]); 269 } else { 270 // 取出场景中的属性名称 271 $scenarios[$scenario] = array_keys($attributes); 272 } 273 } 274 275 return $scenarios; 276 }
未完待续
以上是关于yii2源码学习笔记(六)的主要内容,如果未能解决你的问题,请参考以下文章