• yii2源码学习笔记(六)


    Behvaior类,Behavior类是所有事件类的基类:

    目录yii2aseBehavior.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 yiibase;
     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 <qiang.xue@gmail.com>
    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类,它是所有模型的基类

    目录yii2aseModel.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 yiibase;
      9 
     10 use Yii;
     11 use ArrayAccess;
     12 use ArrayObject;
     13 use ArrayIterator;
     14 use ReflectionClass;
     15 use IteratorAggregate;
     16 use yiihelpersInflector;
     17 use yiivalidatorsRequiredValidator;
     18 use yiivalidatorsValidator;
     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 yiivalidatorsValidator[] $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|yiivalidatorsValidator[] $validators All the validators declared in the model.
     60  * This property is read-only.
     61  *
     62  * @author Qiang Xue <qiang.xue@gmail.com>
     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     }

    未完待续

  • 相关阅读:
    leetcode 131. Palindrome Partitioning
    leetcode 526. Beautiful Arrangement
    poj 1852 Ants
    leetcode 1219. Path with Maximum Gold
    leetcode 66. Plus One
    leetcode 43. Multiply Strings
    pytorch中torch.narrow()函数
    pytorch中的torch.repeat()函数与numpy.tile()
    leetcode 1051. Height Checker
    leetcode 561. Array Partition I
  • 原文地址:https://www.cnblogs.com/dragon16/p/5532430.html
Copyright © 2020-2023  润新知