
php
Yii2规则用于验证模型属性. 方案用户定义在不同方案中需要验证的模型. 以下文章主要介绍有关Yii2中的方案(方案)和验证规则(规则)的相关信息. 本文将详细介绍示例代码,需要它的朋友可以参考它.
前言
一个顾名思义的场景就是一个场景,一个场景. yii2中也有场景,该场景与您理解的场景含义相同.
与用户交互的系统的基本功能包括收集用户数据,检查和处理. 在实际业务中yii2.0 验证规则,经常需要持久存储数据. 出于安全原因,开发人员应牢牢把握“不信任客户输入”的原则. 客户端传递的数据在存储或传递到内部系统之前会被过滤和清除.
Yii2建议使用Model类来收集和验证用户数据,而持久ActiveRecord类是其子类. Model类的load和validate方法分别用于收集和验证客户端数据. 在本文的主题是方案和验证规则的情况下,应该收集哪些数据以及需要验证哪些数据.
因为我不想说太多,所以让我们来看看编辑器的详细介绍.
系统结构
首先介绍一个简单的业务系统: 系统中有两个学生角色和教师角色,中使用了三个表来存储角色信息:
用户: [id,用户名,密码,状态,其他常见属性]
学生: [id,user_id,student_no,等级,班级,其他学生属性]

老师: [id,user_id,work_no,职称,电话,其他教师属性]
实际业务不限于这三个表的添加,删除和修改. 为了简化问题,稍后将仅讨论用户和学生这两个表的数据更改(给出了教师表,以使读者不会认为设计的人会受到大脑的损害: 可以放在一张桌子上,为什么要拆开它!)
学生注册
学生注册是典型的添加,删除和更正操作,并且发送子问题. 学生注册的示例代码如下:
public function actionSignup()
{
$data = Yii::$app->request->post();
$user = new User();
$user->load($data);
if ($user->save()) {
$student = new Student([
"user_id" => $user->id,
]);
$student->load($data);
if ($student->save()) {
// redirect to success page
} else {
$user->delete();
}
}
// render error page
}
我相信具有Yii2经验的人可以根据字段约束快速编写User和Student类的rule方法. 例如,用户文件的内容可能如下:
namespace app\models;
class User extends \yii\db\ActiveRecord
{
public function rules()
{
return [ [["username", "password", "status",], "required"],
["username", "unique"],
// other rules
];
}
// other method
}
定义数据验证规则. 这是大多数人对规则的第一印象yii2.0 验证规则,这是一个很好的印象: 它返回非法数据并允许正常数据进入系统. 安全实践应尝试定义完整的规则以完全验证数据. 还建议每个Yii2开发人员都熟悉内置的核心检查器.
编辑信息
修改信息也是典型的添加,删除和检查操作. 实现代码和注册没有太大区别. 这里仅讨论两点:
1. 用户密码验证

注册时,它将验证用户密码是否为8-16位数字. 密码规则可以是: [“ password”,“ string”,“ length” => [8,16]]. 建议不要以纯文本形式保存密码. 插入时至少要进行MD5加密,并且密码将变为32位. 假定用户在修改信息时未更改密码,则无法保存再次保存时密码规则检查错误(长度不匹配)!
如何解决这个问题?查看Yii文档,我发现规则中的when属性可以保存该字段. 一种可能的验证规则是:
public function rules()
{
return [
["password", "string", "length" => [8, 16], when => function ($model) {
return $model->isNewRecord;
}],
// other rules
];
仅在注册(添加数据)时验证密码字段. 问题已解决,完美!
2. 防止用户私下更改密码
假设有一个聪明的家伙(例如Tom)发现该系统是由Yii框架组成的,并且想要对它进行一点破坏以炫耀它的水平. 发送表单修改信息时,Tom添加&password = 12345678这条数据. 系统使用$ user-> load($数据)收集用户输入并更新密码字段,结果如下: 规则字段在更新时不检查密码字段,并且12345678作为密码直接保存在中. 密码的值. 此操作会产生连锁反应: 当用户再次登录时,加密密码与中的明文密码不匹配,这将阻止Tom登录系统. 令人讨厌的是,汤姆是一根刺,他不必担心登录后整天骚扰客户服务!
如何防止这种情况发生?一种解决方案是防止密码更改:
unset($data["password"]); $user->load($data); // 或者 $password = $user->password; $user->load($data); $user->password = $password;
过滤掉用户输入的密码,解决了私下修改密码的问题.
但是问题还没有解决: Tom可以修改其他字段,例如性别,ID等. 更严重的情况是修改了Student中的user_id,您可以更改任何学生的信息. 问题很严重,漏洞需要立即修复.
您可以根据密码方法一个一个地阻止受保护的属性,但是看起来很冗长(尽管易于使用). 如果有许多受保护的属性,则只能允许白名单条目. 具体操作是: 添加一个UpdateInfoForm类以继承Model,并且该属性为白名单属性的总和. 使用UpdateInfoForm筛选用户数据,然后在验证后更新为用户和学生:

$form = new UpdateInfoForm();
$form->load($data);
if ($form->validate()) {
$user->load($form->attributes);
$student->load($form->attributes);
// next biz
}
这种方法更优雅,但是如果仔细考虑一下,代价会不小: 必须重新编写属性和验证规则;用户和学生反复保存并验证属性. 这种方法看起来不错,但实际上是多余且效率低下的.
方案首次亮相,是解决上述问题的完美解决方案.
场景(场景)
分析上述问题,您会发现关键点是两种方法: 批量分配和验证. 如果将值字段和检查规则分配给不同的方案,则可以解决问题.
Yii中的场景具有两个概念: 安全属性和活动属性. 安全属性用于批处理分配的加载方法中. 只能分配安全属性. 活动属性用于规则验证的validate方法中. 验证定义验证规则的活动属性集中的属性. 活动属性与安全属性之间的关系是,安全属性是活动属性的子集.
The
\ yii \ base \ Model类定义默认场景: SCENARIO_DEFAULT(默认值). 在默认情况下,规则方法中显示的属性既是活动属性又是安全属性(此句子基本上是正确的,请参阅后续说明). 通过覆盖Senarios或规则的两种方法(几乎每个Model类都将覆盖rules方法,而Senario的使用较少),可以为不同的场景指定活动属性,安全属性和验证器.
规则
首先查看rules方法. 默认属性加上验证器定义意味着每个属性既是安全属性又是活动属性. 如果要使属性不是安全属性(不能通过加载分配值),请在属性名称前添加感叹号!例如,student中的user_id字段:
public function rules()
{
return [
["!user_od", "required"],
["!user_id", "integer"],
["!user_od", "unique"],
// other rules
];
}

user_id是活动属性,将在写入时进行验证. 但是,它不是安全属性,不能通过load方法进行分配,从而解决了安全隐患.
查看rule方法,以按场景区分验证器规则: 定义验证器时,on属性指定规则生效的场景,except属性排除某些场景(如果未指定on和except,该规则适用于所有有效场景). 例如:
public function rules()
{
return [
["password", "string", "length" => [8, 16], "on" => ["signup"]], // 仅在signup场景时才被验证
["status", "integer", "except" => ["signup"], // 除了signup场景,其他情况都校验
// other rules
];
}
感叹号和on / except属性是在原始基础上添加的. 在不同情况下定义非安全属性并指定验证规则非常简单.
场景
更清晰地定义安全性属性和活动属性的另一种方法是重写场景方法. 场景方法返回一个数组. 数组的键是方案的名称,值是一组活动属性(餐点的安全属性). 例如,student表的可能实现如下:
public function scenarios()
{
return [
self::SCENARIO_DEFAULT => ["!user_id", "grade", "class", xxxx],
"update" => ["grade", "class", xxxx],
];
}
默认情况下(学生注册),年级和班级信息是安全属性,而user_id不是. 它只能在程序内分配,并在插入数据时进行验证;修改信息时,user_id不是活动属性,不能批量分配或验证(实际上不应更改).
“方案”方法只能定义活动属性和安全属性,而不能定义验证规则. 它需要与规则结合使用.
摘要
Kim Ken定义了明确定义的数据验证规则
在业务复杂时定义多个方案,为每个方案仔细定义安全属性和验证规则
使用规则之前;在属性很多且规则复杂的情况下,可以使用场景方法快速筛选出安全属性和活动属性
好的,以上是本文的全部内容,希望本文的内容对大家的学习或工作具有一定的参考价值. 如有任何疑问,可以留言交流,谢谢您对脚本库的支持.
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-187026-1.html
该不会是冥钞吧
潜艇