yii2框架随笔15

系统的看一下model.php

<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */
namespace yii\base;
use Yii;
use ArrayAccess;
use ArrayObject;
use ArrayIterator;
use ReflectionClass;
use IteratorAggregate;
use yii\helpers\Inflector;
use yii\validators\RequiredValidator;
use yii\validators\Validator;
/**
 * Model is the base class for data models.
 * Model 是所有模型的基类
 * IteratorAggregate(聚合式迭代器)接口 — 创建外部迭代器的接口, 需实现 getIterator 方法。
 * IteratorAggregate::getIterator — 获取一个外部迭代器, foreach 会调用该方法。
 *
 * ArrayAccess(数组式访问)接口 — 提供像访问数组一样访问对象的能力的接口, 需实现如下方法:
 * ArrayAccess::offsetExists — 检查一个偏移位置是否存在
 * ArrayAccess::offsetGet — 获取一个偏移位置的值
 * ArrayAccess::offsetSet — 设置一个偏移位置的值
 * ArrayAccess::offsetUnset — 复位一个偏移位置的值
 * 在 Model 中用于实现将 $model[$field] 替换为 $model->$field
 *
 * Model implements the following commonly used features:
 * 模型实现了以下常用的特性:
 * - attribute declaration: by default, every public class member is considered as
 *   a model attribute
 *   属性声明:默认情况下,每一个公共类成员被认为是一个模型属性.
 * - attribute labels: each attribute may be associated with a label for display purpose
 * 属性标签:每个属性可能与一个标签显示的目的相关联
 * - massive attribute assignment
 * 大规模属性赋值
 * - scenario-based validation
 * 基于场景的验证
 * Model also raises the following events when performing data validation:
 * Model在执行数据验证的时候也会触发以下事件。
 * - [[EVENT_BEFORE_VALIDATE]]: an event raised at the beginning of [[validate()]]
 * 一个事件在数据验证前的
 * - [[EVENT_AFTER_VALIDATE]]: an event raised at the end of [[validate()]]
 * 一个事件在数据验证后的
 * You may directly use Model to store model data, or extend it with customization.
 * 你可以直接用Model来储存数据模型,也可以自己自定义。
 * @property \yii\validators\Validator[] $activeValidators The validators applicable to the current
 * [[scenario]]. This property is read-only. 这个属性是只读的。
 * @property array $attributes Attribute values (name => value).
 * @property array $errors An array of errors for all attributes. Empty array is returned if no error. The
 * result is a two-dimensional array. See [[getErrors()]] for detailed description. This property is read-only.
 * 错误数组返回所有属性的错误信息,没错误时数组为空。也是只读的。
 * @property array $firstErrors The first errors. The array keys are the attribute names, and the array values
 * are the corresponding error messages. An empty array will be returned if there is no error. This property is
 * read-only.
 * 数组中的第一个错误,数组的键为属性名称,数组的值为相应的错误消息。如果没有错误,将返回一个空数组。也是只读的。

 * @property ArrayIterator $iterator An iterator for traversing the items in the list. This property is
 * read-only.
 * 迭代器属性,遍历列表中项目的迭代器,属性也是只读的。
 * @property string $scenario The scenario that this model is in. Defaults to [[SCENARIO_DEFAULT]].
 * 这个模型的场景,默认为[[SCENARIO_DEFAULT]].
 * @property ArrayObject|\yii\validators\Validator[] $validators All the validators declared in the model.
 * validators属性,模型中的所有验证器模型.
 * This property is read-only.
 * 只读
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @since 2.0
 */
class Model extends Component implements IteratorAggregate, ArrayAccess, Arrayable
{
    use ArrayableTrait;//使用ArrayableTrait,类似于继承了一个arrayable类
    /**
     * The name of the default scenario.
     * 默认场景的名称
     */
    const SCENARIO_DEFAULT = 'default';
    /**
     * @event ModelEvent an event raised at the beginning of [[validate()]]. You may set
     * [[ModelEvent::isValid]] to be false to stop the validation.
     * [[validate()]]开始前触发的事件常量,通过设置[[ModelEvent::isValid]]停用
     */
    const EVENT_BEFORE_VALIDATE = 'beforeValidate';
    /**
     * @event Event an event raised at the end of [[validate()]]
     * 事件常量在[[validate()]]结束后触发。
     */
    const EVENT_AFTER_VALIDATE = 'afterValidate';
    /**
     * @var array validation errors (attribute name => array of errors)
     * 验证的错误信息
     */
    private $_errors;
    /**
     * @var ArrayObject list of validators
     * ArrayObject验证器列表
     */
    private $_validators;
    /**
     * @var string current scenario
     * 当前的场景,默认是default
     */
    private $_scenario = self::SCENARIO_DEFAULT;
    /**
     * Returns the validation rules for attributes.
     *
     * 返回属性的验证规则
     *
     * Validation rules are used by [[validate()]] to check if attribute values are valid.
     * Child classes may override this method to declare different validation rules.
     * 如果属性值是有效的,验证规则使用[[validate()))检查。
     * 子类可以重写此方法声明不同的验证规则。
     * Each rule is an array with the following structure:
     * 格式如下:
     *
     * ~~~
     * [
     *     ['attribute1', 'attribute2'], //属性列表
     *     'validator type', //验证的类型
     *     'on' => ['scenario1', 'scenario2'],//应用的场景
     *     ...other parameters... //其他的参数
     * ]
     * ~~~
     *
     * where
     *
     *  - attribute list: required, specifies the attributes array to be validated, for single attribute you can pass string;
     *   属性名称列表:必选, 指定要验证的属性名称
     *  - validator type: required, specifies the validator to be used. It can be a built-in validator name,
     *  验证器类型:要求,指定验证器使用。它可以是一个内置验证器的名字,
     *    a method name of the model class, an anonymous function, or a validator class name.
     *    模型类的方法名称,一个匿名函数,或者一个确认器类的名字。
     *  - on: optional, specifies the [[scenario|scenarios]] array when the validation
     *  指定了可选的数组验证参数
     *    rule can be applied. If this option is not set, the rule will apply to all scenarios.
     *    如果没有设置这个选项,规则将适用于所有情况。
     *  - additional name-value pairs can be specified to initialize the corresponding validator properties.
     *    Please refer to individual validator class API for possible properties.
     *
     * A validator can be either an object of a class extending [[Validator]], or a model class method
     * (called *inline validator*) that has the following signature:
     * validator可以是[[Validator]]的一个实例,也可以是模型model的方法
     * ~~~
     * // $params refers to validation parameters given in the rule
     * 验证参数给出的规则。
     * function validatorName($attribute, $params)
     * ~~~
     *
     * In the above `$attribute` refers to currently validated attribute name while `$params` contains an array of
     * validator configuration options such as `max` in case of `string` validator. Currently validate attribute value
     * can be accessed as `$this->[$attribute]`.
     *
     * Yii also provides a set of [[Validator::builtInValidators|built-in validators]].
     * They each has an alias name which can be used when specifying a validation rule.
     *他们每个人都有一个别名时,可以使用指定的验证规则。
     * Below are some examples:
     *
     * ~~~
     * [
     *     // built-in "required" validator
     *     [['username', 'password'], 'required'],
     *     // built-in "string" validator customized with "min" and "max" properties
     *     ['username', 'string', 'min' => 3, 'max' => 12],
     *     // built-in "compare" validator that is used in "register" scenario only
     *     ['password', 'compare', 'compareAttribute' => 'password2', 'on' => 'register'],
     *     // an inline validator defined via the "authenticate()" method in the model class
     *     ['password', 'authenticate', 'on' => 'login'],
     *     // a validator of class "DateRangeValidator"
     *     ['dateRange', 'DateRangeValidator'],
     * ];
     * ~~~
     *
     * Note, in order to inherit rules defined in the parent class, a child class needs to
     * merge the parent rules with child rules using functions such as `array_merge()`.
     * 如果想继承父类中的验证规则,需要通过array_merge()函数合并验证规则数组
     * @return array validation rules
     * @see scenarios()
     */
    public function rules()
    {
        return [];
    }
    /**
     * Returns a list of scenarios and the corresponding active attributes.
     * An active attribute is one that is subject to validation in the current scenario.
     * 返回场景及与之对应的 active 属性的列表
     * The returned array should be in the following format:
     *
     * ~~~
     * [
     *     'scenario1' => ['attribute11', 'attribute12', ...],
     *     'scenario2' => ['attribute21', 'attribute22', ...],
     *     ...
     * ]
     * ~~~
     *
     * By default, an active attribute is considered safe and can be massively assigned.
     * 默认情况下,一个活跃的属性被认为是安全的,可以大规模分配。
     * If an attribute should NOT be massively assigned (thus considered unsafe),
     * 如果一个属性不应该大规模分配(这会被认为是不安全的),
     * please prefix the attribute with an exclamation character (e.g. '!rank').
     * 请在感叹字符前加一个前缀属性例如(e.g. '!rank').
     * The default implementation of this method will return all scenarios found in the [[rules()]]
     * declaration.
     * 默认该方法的实现将会返回所有场景中发现的[rules()]方法的声明。
     *  A special scenario named [[SCENARIO_DEFAULT]] will contain all attributes
     * found in the [[rules()]].
     * 一个特殊的场景叫[[SCENARIO_DEFAULT]]将包含所有属性
     * 在[[rules()]]里。
     *
     * @return array a list of scenarios and the corresponding active attributes.
     */
    public function scenarios()
    {
        // 默认有 default 的场景
        $scenarios = [self::SCENARIO_DEFAULT => []];
        foreach ($this->getValidators() as $validator) {
            // 循环 validator,取出所有提到的场景,包括 on 和 except
            foreach ($validator->on as $scenario) {
                $scenarios[$scenario] = [];
            }
            foreach ($validator->except as $scenario) {
                $scenarios[$scenario] = [];
            }
        }
        // 取出所有场景的名称
        $names = array_keys($scenarios);
        foreach ($this->getValidators() as $validator) {
            if (empty($validator->on) && empty($validator->except)) {
                // 如果 validator 即没有定义 on,也没有定义 except,就放到所有的场景中
                foreach ($names as $name) {
                    // 循环 $validator 的所有属性
                    foreach ($validator->attributes as $attribute) {
                        $scenarios[$name][$attribute] = true;
                    }
                }
            } elseif (empty($validator->on)) {
                // 如果没有定义 on
                foreach ($names as $name) {
                    if (!in_array($name, $validator->except, true)) {
                        // 而且场景不在 except 中, 就将这个属性加入到相应的场景中
                        foreach ($validator->attributes as $attribute) {
                            $scenarios[$name][$attribute] = true;
                        }
                    }
                }
            } else {
                // 如果定义了 on
                foreach ($validator->on as $name) {
                    // 就将这个属性加入到 on 定义的场景中
                    foreach ($validator->attributes as $attribute) {
                        $scenarios[$name][$attribute] = true;
                    }
                }
            }
        }

 

posted @ 2016-04-25 23:30  TTKKK  阅读(220)  评论(0编辑  收藏  举报