Yii源码阅读笔记(十四)

Model类,集中整个应用的数据和业务逻辑——场景、属性和标签:

  1  /**
  2      * Returns a list of scenarios and the corresponding active attributes.
  3      * An active attribute is one that is subject to validation in the current scenario.
  4      * 返回所有场景及与之对应的 active 属性的列表
  5      * active 属性是指在默认场景中验证的
  6      * The returned array should be in the following format:
  7      * 返回的格式如下:
  8      * ```php
  9      * [
 10      *     ‘scenario1‘ => [‘attribute11‘, ‘attribute12‘, ...],
 11      *     ‘scenario2‘ => [‘attribute21‘, ‘attribute22‘, ...],
 12      *     ...
 13      * ]
 14      * ```
 15      *
 16      * By default, an active attribute is considered safe and can be massively assigned.
 17      * 默认情况下,一个active属性被认为是安全的,可以被批量赋值
 18      * If an attribute should NOT be massively assigned (thus considered unsafe),
 19      * 如果不允许批量赋值,则在属性名称前面加“!”
 20      * please prefix the attribute with an exclamation character (e.g. `‘!rank‘`).
 21      *
 22      * The default implementation of this method will return all scenarios found in the [[rules()]]
 23      * declaration. A special scenario named [[SCENARIO_DEFAULT]] will contain all attributes
 24      * found in the [[rules()]]. Each scenario will be associated with the attributes that
 25      * are being validated by the validation rules that apply to the scenario.
 26      * 默认情况下会返回[[rules()]]中定义的所有场景,其中[[SCENARIO_DEFAULT]] 默认场景包含所有的属性
 27      * 每个场景对应的属性值将按指定的验证规则验证
 28      *
 29      * @return array a list of scenarios and the corresponding active attributes.
 30      */
 31     public function scenarios()
 32     {
 33         // 默认情况下有default 的场景
 34         $scenarios = [self::SCENARIO_DEFAULT => []];
 35         foreach ($this->getValidators() as $validator) {
 36             // 遍历validator,取出所有提到的场景,包括 on 和 except
 37             foreach ($validator->on as $scenario) {
 38                 $scenarios[$scenario] = [];
 39             }
 40             foreach ($validator->except as $scenario) {
 41                 $scenarios[$scenario] = [];
 42             }
 43         }
 44         // 取出所有场景的名称
 45         $names = array_keys($scenarios);
 46
 47         foreach ($this->getValidators() as $validator) {
 48             if (empty($validator->on) && empty($validator->except)) {
 49                 // 如果 validator 即没有定义 on,也没有定义 except,就放到所有的场景中
 50                 foreach ($names as $name) {
 51                     // 循环 $validator 的所有属性
 52                     foreach ($validator->attributes as $attribute) {
 53                         $scenarios[$name][$attribute] = true;
 54                     }
 55                 }
 56             } elseif (empty($validator->on)) {
 57                 // 如果没有定义 on
 58                 foreach ($names as $name) {
 59                     if (!in_array($name, $validator->except, true)) {
 60                         // 而且场景不在 except 中, 就将这个属性加入到相应的场景中
 61                         foreach ($validator->attributes as $attribute) {
 62                             $scenarios[$name][$attribute] = true;
 63                         }
 64                     }
 65                 }
 66             } else {
 67                 // 如果定义了 on
 68                 foreach ($validator->on as $name) {
 69                     // 就将这个属性加入到 on 定义的场景中
 70                     foreach ($validator->attributes as $attribute) {
 71                         $scenarios[$name][$attribute] = true;
 72                     }
 73                 }
 74             }
 75         }
 76
 77         /**
 78          * 将 $scenarios 从
 79          *
 80          * ~~~
 81          * [
 82          *     ‘default‘ => [],
 83          *     ‘scenario1‘ => [‘attribute11‘ => true, ‘attribute12‘ => true, ...],
 84          *     ‘scenario2‘ => [‘attribute21‘ => true, ‘attribute22‘ => true, ...],
 85          *     ‘scenario3‘ => [],
 86          *     ...
 87          * ]
 88          * ~~~
 89          * 转化为
 90          * ~~~
 91          * [
 92          *     ‘default‘ => [],
 93          *     ‘scenario1‘ => [‘attribute11‘, ‘attribute12‘, ...],
 94          *     ‘scenario2‘ => [‘attribute21‘, ‘attribute22‘, ...],
 95          *     ...
 96          * ]
 97          * ~~~
 98          */
 99         foreach ($scenarios as $scenario => $attributes) {
100             // 去除掉没有属性值的场景
101             if (!empty($attributes)) {
102                 // 取出场景中的属性名称
103                 $scenarios[$scenario] = array_keys($attributes);
104             }
105         }
106
107         return $scenarios;
108     }
109
110     /**
111      * Returns the form name that this model class should use.
112      *
113      * 返回表单的名称,就是这个 model 的类名,类名即表名
114      *
115      * The form name is mainly used by [[\yii\widgets\ActiveForm]] to determine how to name
116      * the input fields for the attributes in a model. If the form name is "A" and an attribute
117      * name is "b", then the corresponding input name would be "A[b]". If the form name is
118      * an empty string, then the input name would be "b".
119      * 表单名称用于[[\yii\widgets\ActiveForm]]确定模型中的属性名对应的输入域的名称
120      * 如果表单名为A,属性名为b,对应的输入名为A[b],如果表单名为空,则输入名为b
121      *
122      * The purpose of the above naming schema is that for forms which contain multiple different models,
123      * the attributes of each model are grouped in sub-arrays of the POST-data and it is easier to
124      * differentiate between them.
125      * 上述命名模式的目的是,对于包含多个不同模型的表单,每个模型的属性分组在对应的表单名下的数组,能更好的区分它们
126      *
127      * By default, this method returns the model class name (without the namespace part)
128      * as the form name. You may override it when the model is used in different forms.
129      * 默认情况下该方法返回不包含命名空间的类名称,可以通过重写使用别的表名
130      *
131      * @return string the form name of this model class.
132      * @see load()
133      */
134     public function formName()
135     {
136         // ReflectionClass 类,是php内置的反射类,用于获取类的信息,包含了一个类的有关信息
137         $reflector = new ReflectionClass($this);
138         // 获取类的短名,就是不含命名空间(namespace)的那一部分
139         return $reflector->getShortName();
140     }
141
142     /**
143      * Returns the list of attribute names.
144      * 返回属性名的列表
145      *
146      * By default, this method returns all public non-static properties of the class.
147      * You may override this method to change the default behavior.
148      * 默认只会返回 public 且不是 static 的属性,可以重写该方法定义不同的返回类型
149      *
150      * @return array list of attribute names.
151      */
152     public function attributes()
153     {
154         $class = new ReflectionClass($this);
155         $names = [];
156         /**
157          *ReflectionClass::getProperties — ReflectionClass反射类的方法,用于获取一组属性,有下列参数:
158           ReflectionProperty::IS_STATIC 表示返回 static 的属性。
159           ReflectionProperty::IS_PUBLIC 表示返回 public 的属性。
160           ReflectionProperty::IS_PROTECTED 表示返回 protected 的属性。
161           ReflectionProperty::IS_PRIVATE 表示返回 private 的属性。
162          */
163         foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) {
164             // 如果是public的属性,并且不是static的,就认为是它的attribute
165             if (!$property->isStatic()) {
166                 // 获取该属性的名称
167                 $names[] = $property->getName();
168             }
169         }
170
171         return $names;
172     }
173
174     /**
175      * Returns the attribute labels.
176      * 返回属性的标签
177      *
178      * Attribute labels are mainly used for display purpose. For example, given an attribute
179      * `firstName`, we can declare a label `First Name` which is more user-friendly and can
180      * be displayed to end users.
181      * 属性标签主要用于显示目的,例如给属性‘firstName‘一个‘First Name’标签,能够更友好的显示给最终用户
182      *
183      * By default an attribute label is generated using [[generateAttributeLabel()]].
184      * This method allows you to explicitly specify attribute labels.
185      * 默认调用[[generateAttributeLabel()]]方法生成标签
186      * Note, in order to inherit labels defined in the parent class, a child class needs to
187      * merge the parent labels with child labels using functions such as `array_merge()`.
188      * 注意,为了继承父类的标签,之类需要调用`array_merge()`合并父类的标签
189      *
190      * @return array attribute labels (name => label)
191      * @see generateAttributeLabel()
192      */
193     public function attributeLabels()
194     {
195         return [];
196     }
时间: 2024-10-22 21:48:26

Yii源码阅读笔记(十四)的相关文章

Yii源码阅读笔记(四)

所有控制器action的基类yii\base\Action.php 1 namespace yii\base;//定义的命名空间 2 3 use Yii //使用的命名空间 4 5 class Action extends Component //继承了组建类 6 { 7 8 //定义属性action的id 9 10 public $id; 11 14 public $controller; //定义拥有该action的控制器属性 15 24 public function __construc

Yii源码阅读笔记 - 日志组件

?使用 Yii框架为开发者提供两个静态方法进行日志记录: Yii::log($message, $level, $category);Yii::trace($message, $category); 两者的区别在于后者依赖于应用开启调试模式,即定义常量YII_DEBUG: defined('YII_DEBUG') or define('YII_DEBUG', true); Yii::log方法的调用需要指定message的level和category.category是格式为“xxx.yyy.z

Yii源码阅读笔记(一)

今天开始阅读yii2的源码,想深入了解一下yii框架的工作原理,同时学习一下优秀的编码规范和风格.在此记录一下阅读中的小心得. 每个框架都有一个入口文件,首先从入口文件开始,yii2的入口文件位于web目录的index.php,用于启动web应用和配置一些路径参数. index.php—— 1 // comment out the following two lines when deployed to production 2 defined('YII_DEBUG') or define('Y

Yii源码阅读笔记(三十四)

Instance类, 表示依赖注入容器或服务定位器中对某一个对象的引用 1 namespace yii\di; 2 3 use Yii; 4 use yii\base\InvalidConfigException; 5 6 /** 7 * Instance represents a reference to a named object in a dependency injection (DI) container or a service locator. 8 * Instance 表示依赖

Yii源码阅读笔记(二十四)

Module类中获取子模块,注册子模块,实例化控制器,根据路由运行指定控制器方法的注释: 1 /** 2 * Retrieves the child module of the specified ID. 3 * 取出指定模块的子模块 4 * This method supports retrieving both child modules and grand child modules. 5 * 该方法支持检索子模块和子模块的子模块 6 * @param string $id module

Yii源码阅读笔记(二十六)

Application 类中设置路径的方法和调用ServiceLocator(服务定位器)加载运行时的组件的方法注释: 1 /** 2 * Handles the specified request. 3 * 处理指定的请求--抽象方法 4 * This method should return an instance of [[Response]] or its child class 5 * which represents the handling result of the reques

Yii源码阅读笔记(三十五)

Container,用于动态地创建.注入依赖单元,映射依赖关系等功能,减少了许多代码量,降低代码耦合程度,提高项目的可维护性. 1 namespace yii\di; 2 3 use ReflectionClass; 4 use Yii; 5 use yii\base\Component; 6 use yii\base\InvalidConfigException; 7 use yii\helpers\ArrayHelper; 8 9 /** 10 * Container implements

Yii源码阅读笔记(三十二)

web/Application类的注释,继承base/Application类,针对web应用的一些处理: 1 namespace yii\web; 2 3 use Yii; 4 use yii\base\InvalidRouteException; 5 6 /** 7 * Application is the base class for all web application classes. 8 * Application 是所有web应用的基类 9 * 10 * @property st

Yii源码阅读笔记(二十二)

Module类,属性的注释和构造函数的注释: 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 yii\di\ServiceLocator;