Yii源码阅读笔记(十五)
Model类,集中整个应用的数据和业务逻辑——验证
/**
* Returns the attribute labels.
* 返回属性的标签
*
* Attribute labels are mainly used for display purpose. For example, given an attribute
* `firstName`, we can declare a label `First Name` which is more user-friendly and can
* be displayed to end users.
* 属性标签主要用于显示目的,例如给属性'firstName'一个‘First Name’标签,能够更友好的显示给最终用户
*
* By default an attribute label is generated using [[generateAttributeLabel()]].
* This method allows you to explicitly specify attribute labels.
* 默认调用[[generateAttributeLabel()]]方法生成标签
* Note, in order to inherit labels defined in the parent class, a child class needs to
* merge the parent labels with child labels using functions such as `array_merge()`.
* 注意,为了继承父类的标签,之类需要调用`array_merge()`合并父类的标签
*
* @return array attribute labels (name => label)
* @see generateAttributeLabel()
*/
public function attributeLabels()
{
return [];
}
/**
* Returns the attribute hints.
* 返回属性提示
* Attribute hints are mainly used for display purpose. For example, given an attribute
* `isPublic`, we can declare a hint `Whether the post should be visible for not logged in users`,
* which provides user-friendly description of the attribute meaning and can be displayed to end users.
* 属性提示主要用于显示目的,例如给一个属性`isPublic`,我们能够设置一个 `是否显示给最终用户` 的提示,
* Unlike label hint will not be generated, if its explicit declaration is omitted.
*
* Note, in order to inherit hints defined in the parent class, a child class needs to
* merge the parent hints with child hints using functions such as `array_merge()`.
*
* @return array attribute hints (name => hint)
* @since 2.0.4
*/
public function attributeHints()
{
return [];
}
/**
* Performs the data validation.
* 执行数据验证
*
* This method executes the validation rules applicable to the current [[scenario]].
* 该方法执行指定场景下的数据验证
* The following criteria are used to determine whether a rule is currently applicable:
* 下面的标准来确定一个规则是否适用:
*
* - the rule must be associated with the attributes relevant to the current scenario;
* 规则必须与当前场景相关的属性关联
* - the rules must be effective for the current scenario.
* 规则必须是有效的当前场景
*
* This method will call [[beforeValidate()]] and [[afterValidate()]] before and
* after the actual validation, respectively. If [[beforeValidate()]] returns false,
* the validation will be cancelled and [[afterValidate()]] will not be called.
* 该方法会调用[[beforeValidate()]] 和[[afterValidate()]]方法
*
* Errors found during the validation can be retrieved via [[getErrors()]],
* [[getFirstErrors()]] and [[getFirstError()]].
* 验证的错误信息可以通过[[getErrors()]],[[getFirstErrors()]]和 [[getFirstError()]].方法获取
*
* @param array $attributeNames list of attribute names that should be validated.
* If this parameter is empty, it means any attribute listed in the applicable
* validation rules should be validated.
* @param boolean $clearErrors whether to call [[clearErrors()]] before performing validation
* @return boolean whether the validation is successful without any error.
* @throws InvalidParamException if the current scenario is unknown.
*/
public function validate($attributeNames = null, $clearErrors = true)
{
if ($clearErrors) {
//清除所有的错误信息
$this->clearErrors();
}
if (!$this->beforeValidate()) {
//如果beforeValidate()返回false,则终止执行,返回false
return false;
}
//取得所有场景及与之对应的 active 属性的列表
$scenarios = $this->scenarios();
//取得当前使用场景
$scenario = $this->getScenario();
if (!isset($scenarios[$scenario])) {
//判断是否在场景列表中
throw new InvalidParamException("Unknown scenario: $scenario");
}
if ($attributeNames === null) {
//属性名为空,返回所有的active属性
$attributeNames = $this->activeAttributes();
}
foreach ($this->getActiveValidators() as $validator) {
//返回当前场景下的validator,然后遍历验证
$validator->validateAttributes($this, $attributeNames);
}
//调用后置方法afterValidate();
$this->afterValidate();
return !$this->hasErrors();
}
/**
* This method is invoked before validation starts.
* 在验证方法前调用,触发`beforeValidate`事件,用于验证前的初步检查
* The default implementation raises a `beforeValidate` event.
* You may override this method to do preliminary checks before validation.
* Make sure the parent implementation is invoked so that the event can be raised.
* @return boolean whether the validation should be executed. Defaults to true.
* If false is returned, the validation will stop and the model is considered invalid.
*/
public function beforeValidate()
{
$event = new ModelEvent;
$this->trigger(self::EVENT_BEFORE_VALIDATE, $event);
return $event->isValid;
}
/**
* This method is invoked after validation ends.
* 在验证方法后调用,触发`afterValidate`事件,用于验证后的处理
* The default implementation raises an `afterValidate` event.
* You may override this method to do postprocessing after validation.
* Make sure the parent implementation is invoked so that the event can be raised.
*/
public function afterValidate()
{
$this->trigger(self::EVENT_AFTER_VALIDATE);
}
/**
* Returns all the validators declared in [[rules()]].
* 返回在[[rules()]]中定义的所有validators
*
* This method differs from [[getActiveValidators()]] in that the latter
* only returns the validators applicable to the current [[scenario]].
* 该方法不同于[[getActiveValidators()]] ,后者只返回当前场景下的validator
*
* Because this method returns an ArrayObject object, you may
* manipulate it by inserting or removing validators (useful in model behaviors).
* 该方法返回ArrayObject对象,可以进行添加或删除操作,例如:
* For example,
*
* ```php
* $model->validators[] = $newValidator;
* ```
*
* @return ArrayObject|\yii\validators\Validator[] all the validators declared in the model.
*/
public function getValidators()
{
if ($this->_validators === null) {
//_validators中没有值,则调用createValidators()创建Validator
$this->_validators = $this->createValidators();
}
return $this->_validators;
}
/**
* Returns the validators applicable to the current [[scenario]].
* 返回当前场景下的validator
* @param string $attribute the name of the attribute whose applicable validators should be returned.
* If this is null, the validators for ALL attributes in the model will be returned.
* @return \yii\validators\Validator[] the validators applicable to the current [[scenario]].
*/
public function getActiveValidators($attribute = null)
{
$validators = [];
//获取当前模型的使用场景
$scenario = $this->getScenario();
foreach ($this->getValidators() as $validator) {
if ($validator->isActive($scenario) && ($attribute === null || in_array($attribute, $validator->attributes, true))) {
//获取当前场景下的validator
$validators[] = $validator;
}
}
return $validators;
}
/**
* Creates validator objects based on the validation rules specified in [[rules()]].
* 通过[[rules()]]中指定的验证规则生成验证对象
* Unlike [[getValidators()]], each time this method is called, a new list of validators will be returned.
* @return ArrayObject validators
* @throws InvalidConfigException if any validation rule configuration is invalid
*/
public function createValidators()
{
//创建ArrayObject实例
$validators = new ArrayObject;
foreach ($this->rules() as $rule) {
//遍历[[rules()]]
if ($rule instanceof Validator) {
//如果$rule是Validator的实例,则直接写入$validators中
$validators->append($rule);
} elseif (is_array($rule) && isset($rule[0], $rule[1])) { // attributes属性, validator type验证类型
//否则,调用Validator::createValidator生成Validator的实例
$validator = Validator::createValidator($rule[1], $this, (array) $rule[0], array_slice($rule, 2));
$validators->append($validator);
} else {
throw new InvalidConfigException('Invalid validation rule: a rule must specify both attribute names and validator type.');
}
}
return $validators;
}
/**
* Returns a value indicating whether the attribute is required.
* 返回是否该属性值是required
* This is determined by checking if the attribute is associated with a
* [[\yii\validators\RequiredValidator|required]] validation rule in the
* current [[scenario]].
*
* Note that when the validator has a conditional validation applied using
* [[\yii\validators\RequiredValidator::$when|$when]] this method will return
* `false` regardless of the `when` condition because it may be called be
* before the model is loaded with data.
*
* @param string $attribute attribute name
* @return boolean whether the attribute is required
*/
public function isAttributeRequired($attribute)
{
foreach ($this->getActiveValidators($attribute) as $validator) {
if ($validator instanceof RequiredValidator && $validator->when === null) {
return true;
}
}
return false;
}
/**
* Returns a value indicating whether the attribute is safe for massive assignments.
* 返回是否该属性值是批量操作安全的
* @param string $attribute attribute name
* @return boolean whether the attribute is safe for massive assignments
* @see safeAttributes()
*/
public function isAttributeSafe($attribute)
{
return in_array($attribute, $this->safeAttributes(), true);
}
/**
* Returns a value indicating whether the attribute is active in the current scenario.
* 返回是否该属性值是active
* @param string $attribute attribute name
* @return boolean whether the attribute is active in the current scenario
* @see activeAttributes()
*/
public function isAttributeActive($attribute)
{
return in_array($attribute, $this->activeAttributes(), true);
}
/**
* Returns the text label for the specified attribute.
* 返回指定属性的标签
* @param string $attribute the attribute name
* @return string the attribute label
* @see generateAttributeLabel()
* @see attributeLabels()
*/
public function getAttributeLabel($attribute)
{
$labels = $this->attributeLabels();
return isset($labels[$attribute]) ? $labels[$attribute] : $this->generateAttributeLabel($attribute);
}
/**
* Returns the text hint for the specified attribute.
* 返回指定属性的提示信息
* @param string $attribute the attribute name
* @return string the attribute hint
* @see attributeHints()
* @since 2.0.4
*/
public function getAttributeHint($attribute)
{
$hints = $this->attributeHints();
return isset($hints[$attribute]) ? $hints[$attribute] : '';
}
/**
* Returns a value indicating whether there is any validation error.
* 返回某个值是否有验证错误信息
* @param string|null $attribute attribute name. Use null to check all attributes.
* @return boolean whether there is any error.
*/
public function hasErrors($attribute = null)
{
return $attribute === null ? !empty($this->_errors) : isset($this->_errors[$attribute]);
}
/**
* Returns the errors for all attribute or a single attribute.
* 返回全部或者某个属性的验证错误信息
* @param string $attribute attribute name. Use null to retrieve errors for all attributes.
* @property array 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.
* @return array errors for all attributes or the specified attribute. Empty array is returned if no error.
* Note that when returning errors for all attributes, the result is a two-dimensional array, like the following:
* 错误信息的格式为二维数组,键名为属性值,键值为错误信息
* ```php
* [
* 'username' => [
* 'Username is required.',
* 'Username must contain only word characters.',
* ],
* 'email' => [
* 'Email address is invalid.',
* ]
* ]
* ```
*
* @see getFirstErrors()
* @see getFirstError()
*/
public function getErrors($attribute = null)
{
if ($attribute === null) {
return $this->_errors === null ? [] : $this->_errors;
} else {
return isset($this->_errors[$attribute]) ? $this->_errors[$attribute] : [];
}
}
/**
* Returns the first error of every attribute in the model.
* 返回当前模型下每一个属性的第一条错误信息
* @return array 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.
* @see getErrors()
* @see getFirstError()
*/
public function getFirstErrors()
{
if (empty($this->_errors)) {
return [];
} else {
$errors = [];
foreach ($this->_errors as $name => $es) {
if (!empty($es)) {
$errors[$name] = reset($es);
}
}
return $errors;
}
}
/**
* Returns the first error of the specified attribute.
* 返回指定属性的第一条错误信息
* @param string $attribute attribute name.
* @return string the error message. Null is returned if no error.
* @see getErrors()
* @see getFirstErrors()
*/
public function getFirstError($attribute)
{
return isset($this->_errors[$attribute]) ? reset($this->_errors[$attribute]) : null;
}
/**
* Adds a new error to the specified attribute.
* 给指定的属性添加新的错误信息
*
* @param string $attribute attribute name
* @param string $error new error message
*/
public function addError($attribute, $error = '')
{
//将错误信息添加到errors数组中,键名为属性名[],键值为错误信息
$this->_errors[$attribute][] = $error;
}
/**
* Adds a list of errors.
* 添加错误信息列表
* @param array $items a list of errors. The array keys must be attribute names.
* The array values should be error messages. If an attribute has multiple errors,
* these errors must be given in terms of an array.
* You may use the result of [[getErrors()]] as the value for this parameter.
* @since 2.0.2
*/
public function addErrors(array $items)
{
foreach ($items as $attribute => $errors) {
if (is_array($errors)) {
foreach ($errors as $error) {
$this->addError($attribute, $error);
}
} else {
$this->addError($attribute, $errors);
}
}
}
/**
* Removes errors for all attributes or a single attribute.
* 清除所有或者指定属性的错误信息
* @param string $attribute attribute name. Use null to remove errors for all attribute.
*/
public function clearErrors($attribute = null)
{
if ($attribute === null) {
$this->_errors = [];
} else {
unset($this->_errors[$attribute]);
}
}
Yii源码阅读笔记(十五)的更多相关文章
- Yii源码阅读笔记(五)
Object 是一个基础类,实现了属性的功能,其基本内容如下: namespace yii\base; use Yii; /** * Object is the base class that imp ...
- 重新整理 .net core 实践篇——— 权限源码阅读四十五]
前言 简单介绍一下权限源码阅读一下. 正文 一直有人对授权这个事情上争论不休,有的人认为在输入账户密码给后台这个时候进行了授权,因为认为发送了一个身份令牌,令牌里面可能有些用户角色信息,认为这就是授权 ...
- Yii源码阅读笔记(一)
今天开始阅读yii2的源码,想深入了解一下yii框架的工作原理,同时学习一下优秀的编码规范和风格.在此记录一下阅读中的小心得. 每个框架都有一个入口文件,首先从入口文件开始,yii2的入口文件位于we ...
- Mina源码阅读笔记(五)—Mina对连接的操作IoSession
IoSession是Mina管理两端的一个重要部分,也是Mina的核心,Session具有了生命周期的概念,它的生命周期和连接时紧密相关的,这点在后面的介绍中会涉及.另外,好像hibernate中也有 ...
- J.U.C并发框架源码阅读(十五)CopyOnWriteArrayList
基于版本jdk1.7.0_80 java.util.concurrent.CopyOnWriteArrayList 代码如下 /* * Copyright (c) 2003, 2011, Oracle ...
- Yii源码阅读笔记(三十五)
Container,用于动态地创建.注入依赖单元,映射依赖关系等功能,减少了许多代码量,降低代码耦合程度,提高项目的可维护性. namespace yii\di; use ReflectionClas ...
- Yii源码阅读笔记(二十五)
Module类中剩余部分代码,通过控制器ID实例化当前模块的控制器,当前模块的Action方法的前置和后置方法: /** * This method is invoked right before a ...
- Yii源码阅读笔记(三十四)
Instance类, 表示依赖注入容器或服务定位器中对某一个对象的引用 namespace yii\di; use Yii; use yii\base\InvalidConfigException; ...
- Yii源码阅读笔记(三十二)
web/Application类的注释,继承base/Application类,针对web应用的一些处理: namespace yii\web; use Yii; use yii\base\Inval ...
随机推荐
- Linux查看硬件配置信息
转自:http://blog.163.com/yang_jianli/blog/static/1619900062010391127338/ 一:查看cpu more /proc/cpuinfo | ...
- AndroidDev站点推荐-zz
Android-Dev-Bookmarks 项目目前可以生成书签文件导入到浏览器中了,ADB 站点上的内容也是一样的,方便在线浏览.现在内容更新开始按期发布同时也会有个简短的介绍,内容逐渐增多比较难直 ...
- Java Hour 48 Servlet 简介
搞Java Web 开发,绕不开的就是Servlet 了.传说Servlet 是一种比JSP 更加古董的动态网页编程技术.在没有JSP 之前,Servlet 同时充当了展现层,业务逻辑层和持久层. 这 ...
- PHPcms怎么调用二级栏目
{pc:content action=" siteid="$siteid" order="listorder ASC"} {l ...
- hdu 4280 最大流sap
模板套起来 1 5 7 //5个结点,7个边 3 3 //坐标 3 0 3 1 0 0 4 5 1 3 3 //相连的结点和流 2 3 4 2 4 3 1 5 6 4 5 3 1 4 4 3 4 2 ...
- Codeforces Round #350 (Div. 2) F. Restore a Number 模拟构造题
F. Restore a Number Vasya decided to pass a very large integer n to Kate. First, he wrote that num ...
- C++ windows遍历目录
bool Search(TCHAR *Path,TCHAR *File) { HANDLE hFind; WIN32_FIND_DATA wfd; ZeroMemory(&wfd,sizeof ...
- POJ3659 Cell Phone Network(树上最小支配集:树型DP)
题目求一棵树的最小支配数. 支配集,即把图的点分成两个集合,所有非支配集内的点都和支配集内的某一点相邻. 听说即使是二分图,最小支配集的求解也是还没多项式算法的.而树上求最小支配集树型DP就OK了. ...
- AngularJS 表单提交后显示验证信息与失焦后显示验证信息
虽然说AngularJS的实时表单验证非常有用,非常高效方便,但是当用户还没有完成输入时便弹出一个错误提示,这种体验是非常糟糕的. 正常的表单验证逻辑应该是在用户提交表单后或完成当前字段中的输入后,再 ...
- 游戏 window
using UnityEngine; using System.Collections; public class YY : MonoBehaviour { ,,,); ,,,); // Use th ...