zoukankan      html  css  js  c++  java
  • 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     }

    未完待续

  • 相关阅读:
    position+left+bottom+top+right
    C++中的bool类型
    C++读取ini文件
    菜单中Clean和batch build的作用
    解决连接HIS连接不上数据库的问题
    编译错误ERROR C2027
    C++中枚举类型的作用
    用CTime类得到当前日期 时间
    C++中如何调用DLL文件
    #import "msado15.dll" no_namespace rename("EOF","adoEOF")
  • 原文地址:https://www.cnblogs.com/dragon16/p/5532430.html
Copyright © 2011-2022 走看看