Yii2.0模型层数据验证和thinkPHP3.2框架模型层数据验证对比

Yii2.0模型层数据验证

一般说来,程序猿永远不应该信任从最终用户直接接收到的数据,并且使用它们之前应始终先验证其可靠性。要给model填充其所需的用户输入数据,你可以调用
yii\base\Model::validate() 方法验证它们。该方法会返回一个布尔值,指明是否通过验证。若没有通过,你能通过 yii\base\Model::errors 属性获取相应的报错信息。比如

$model = new \app\models\ContactForm;

	// 用用户输入来填充模型的特性
	$model->attributes = \Yii::$app->request->post('ContactForm');

	if ($model->validate()) {
   	 // 若所有输入都是有效的
	} else {
   	 // 有效性验证失败:$errors 属性就是存储错误信息的数组
    		$errors = $model->errors;
	}

声明规则(Rules)

要让 validate() 方法起作用,你需要声明与需验证模型特性相关的验证规则。为此,需要重写
yii\base\Model::rules() 方法。下面的例子展示了如何声明   用于验证 ContactForm 模型的相关验证规则:

public function rules()
{
    return [
        // name,email,subject 和 body 特性是 `require`(必填)的
        [['name', 'email', 'subject', 'body'], 'required'],

        // email 特性必须是一个有效的 email 地址
        ['email', 'email'],
    ];
}

yii\base\Model::rules() 方法应返回一个由规则所组成的数组,每一个规则都呈现为以下这类格式的小数组:

[
    // 必须项,用于指定那些模型特性需要通过此规则的验证。
    // 对于只有一个特性的情况,可以直接写特性名,而不必用数组包裹。
    ['attribute1', 'attribute2', ...],

    // 必填项,用于指定规则的类型。
    // 它可以是类名,验证器昵称,或者是验证方法的名称。
    'validator',

    // 可选项,用于指定在场景(scenario)中,需要启用该规则
    // 若不提供,则代表该规则适用于所有场景
    // 若你需要提供除了某些特定场景以外的所有其他场景,你也可以配置 "except" 选项
    'on' => ['scenario1', 'scenario2', ...],

    // 可选项,用于指定对该验证器对象的其他配置选项
    'property1' => 'value1', 'property2' => 'value2', ...
]

对于每个规则,你至少需要指定该规则适用于哪些特性,以及本规则的类型是什么。你可以指定以下的规则类型之一:

  • 核心验证器的昵称,比如 requiredindate,等等。请参考点击打开链接
  • 模型类中的某个验证方法的名称,或者一个匿名方法。请参考行内验证器小节了解更多。
  • 验证器类的名称。请参考独立验证器小节了解更多。

一个规则可用于验证一个或多个模型特性,且一个特性可以被一个或多个规则所验证。一个规则可以施用于特定场景(scenario),只要指定 on 选项。如果你不指定 on 选项,那么该规则会适配于所有场景。

当调用 validate() 方法时,它将运行以下几个具体的验证步骤:

  1. 检查从声明自 yii\base\Model::scenarios() 方法的场景中所挑选出的当前yii\base\Model::scenario的信息,从而确定出那些特性需要被验证。这些特性被称为激活特性。
  2. 检查从声明自 yii\base\Model::rules() 方法的众多规则中所挑选出的适用于当前yii\base\Model::scenario的规则,从而确定出需要验证哪些规则。这些规则被称为激活规则。
  3. 用每个激活规则去验证每个与之关联的激活特性。

基于以上验证步骤,有且仅有声明在 scenarios() 方法里的激活特性,且它还必须与一或多个声明自 rules() 里的激活规则相关联才会被验证。

自定义错误信息

大多数的验证器都有默认的错误信息,当模型的某个特性验证失败的时候,该错误信息会被返回给模型。比如,用 yii\validators\RequiredValidator 验证器的规则检验 username 特性失败的话,会返还给模型
"Username cannot be blank." 信息。

你可以通过在声明规则的时候同时指定 message 属性,来定制某个规则的错误信息,比如这样:

public function rules()
{
    return [
        ['username', 'required', 'message' => 'Please choose a username.'],
    ];
}

一些验证器还支持用于针对不同原因的验证失败返回更加准确的额外错误信息。比如,yii\validators\NumberValidator 验证器就支持 yii\validators\NumberValidator::tooBig 和 yii\validators\NumberValidator::tooSmall 两种错误消息用于分别返回输入值是太大还是太小。 你也可以像配置验证器的其他属性一样配置它们俩各自的错误信息。

验证事件

当调用 yii\base\Model::validate() 方法的过程里,它同时会调用两个特殊的方法,把它们重写掉可以实现自定义验证过程的目的:

  • yii\base\Model::beforeValidate():在默认的实现中会触发 yii\base\Model::EVENT_BEFORE_VALIDATE 事件。你可以重写该方法或者响应此事件,来在验证开始之前,先进行一些预处理的工作。(比如,标准化数据输入)该方法应该返回一个布尔值,用于标明验证是否通过。
  • yii\base\Model::afterValidate():在默认的实现中会触发 yii\base\Model::EVENT_AFTER_VALIDATE 事件。你可以重写该方法或者响应此事件,来在验证结束之后,再进行一些收尾的工作。

条件式验证

若要只在某些条件满足时,才验证相关特性,比如:是否验证某特性取决于另一特性的值,你可以通过 yii\validators\Validator::when 属性来定义相关条件。举例而言,

[
    ['state', 'required', 'when' => function($model) {
        return $model->country == 'USA';
    }],
]

若你需要支持客户端的条件验证,你应该配置 yii\validators\Validator::whenClient 属性,它会读入一条包含有 JavaScript 函数的字符串。这个函数将被用于确定该客户端验证规则是否被启用。比如,

[
    ['state', 'required', 'when' => function ($model) {
        return $model->country == 'USA';
    }, 'whenClient' => "function (attribute, value) {
        return $('#country').value == 'USA';
    }"],
]

数据预处理

用户输入经常需要进行数据过滤,或者叫预处理。比如你可能会需要先去掉 username 输入的收尾空格。你可以通过使用验证规则来实现此目的。

下面的例子展示了如何去掉输入信息的首尾空格,并将空输入返回为 null。具体方法为通过调用 trim 和 default 核心验证器:

[
    [['username', 'email'], 'trim'],
    [['username', 'email'], 'default'],
]

也还可以用更加通用的 filter(滤镜) 核心验证器来执行更加复杂的数据过滤。

如你所见,这些验证规则并不真的对输入数据进行任何验证。而是,对输入数据进行一些处理,然后把它们存回当前被验证的模型特性。

处理空输入

当输入数据是通过 HTML 表单,你经常会需要给空的输入项赋默认值。你可以通过调整 default 验证器来实现这一点。举例来说,

[
    // 若 "username" 和 "email" 为空,则设为 null
    [['username', 'email'], 'default'],

    // 若 "level" 为空,则设其为 1
    ['level', 'default', 'value' => 1],
]

默认情况下,当输入项为空字符串,空数组,或 null 时,会被视为“空值”。你也可以通过配置 yii\validators\Validator::isEmpty 属性来自定义空值的判定规则。比如,

[
    ['agree', 'required', 'isEmpty' => function ($value) {
        return empty($value);
    }],
]

默认情况下,当输入项为空字符串,空数组,或 null 时,会被视为“空值”。你也可以通过配置 yii\validators\Validator::isEmpty 属性来自定义空值的判定规则。比如,

[
    ['agree', 'required', 'isEmpty' => function ($value) {
        return empty($value);
    }],
]

注意:对于绝大多数验证器而言,若其 yii\base\Validator::skipOnEmpty 属性为默认值 true,则它们不会对空值进行任何处理。也就是当他们的关联特性接收到空值时,相关验证会被直接略过。在 核心验证器 之中,只有 captcha(验证码),default(默认值),filter(滤镜),required(必填),以及 trim(去首尾空格),这几个验证器会处理空输入。

tp3.2模型层数据验证

thinkPHP3.2提供了两种数据验证方式

1.静态验证

所谓静态验证,就是在声明一个模型层时就声明所接收的数据的约束。形式为

<span>	</span>protected $_validate = array(
<span>		</span>array('verify','require','验证码必须!'), //默认情况下用正则进行验证
<span>		</span>array('name','','帐号名称已经存在!',0,'unique',1), // 在新增的时候验证name字段是否唯一
<span>		</span>array('value',array(1,2,3),'值的范围不正确!',2,'in'), // 当值不为空的时候判断是否在一个范围内
<span>		</span>array('repassword','password','确认密码不正确',0,'confirm'), // 验证确认密码是否和密码一致
<span>		</span>array('password','checkPwd','密码格式不正确',0,'function'), // 自定义函数验证密码格式
<span>	</span>);

在数据层中声明$_validate变量,其中单独一条数据验证的格式为

<span>	</span>array("验证字段","验证规则","错误提示",["验证条件","附加规则","验证时间"]),

验证字段,验证规则,错误提示是必须的。

关于验证字段,需要验证的表单字段名称,这个字段不一定是数据库字段,也可以是表单的一些辅助字段,例如确认密码和验证码等等。有个别验证规则和字段       无关的情况下,验证字段是可以随意设置的,例如verify是否输入验证码是和表单字段无关的。如果定义了字段映射的话,这里的验证字段名称应该是实际的数
      据表字段而不是表单字段。

关于验证规则要进行验证的规则,需要结合附加规则,如果在使用正则验证的附加规则情况下,系统还内置了一些常用正则验证的规则,可以直接作为验证规         则使用如下:

        $validate = array(
            'require'=> '/.+/',
            'email' => '/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/',
            'url' => '/^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"])*$/',
            'currency' => '/^\d+(\.\d+)?$/',
            'number' => '/^\d+$/',
            'zip' => '/^[1-9]\d{5}$/',
            'integer' => '/^[-\+]?\d+$/',
            'double' => '/^[-\+]?\d+(\.\d+)?$/',
            'english' => '/^[A-Za-z]+$/',
        );

关于可选的验证条件,包含下面几种情况:

self::EXISTS_VALIDATE 或者0 存在字段就验证(默认)

self::MUST_VALIDATE 或者1 必须验证

self::VALUE_VALIDATE或者2 值不为空的时候验证

附加规则 (可选)

配合验证规则使用,包括下面一些规则:

规则 说明
regex 正则验证,定义的验证规则是一个正则表达式(默认)
function 函数验证,定义的验证规则是一个函数名
callback 方法验证,定义的验证规则是当前模型类的一个方法
confirm 验证表单中的两个字段是否相同,定义的验证规则是一个字段名
equal 验证是否等于某个值,该值由前面的验证规则定义
notequal 验证是否不等于某个值,该值由前面的验证规则定义(3.1.2版本新增)
in 验证是否在某个范围内,定义的验证规则可以是一个数组或者逗号分割的字符串
notin 验证是否不在某个范围内,定义的验证规则可以是一个数组或者逗号分割的字符串(3.1.2版本新增)
length 验证长度,定义的验证规则可以是一个数字(表示固定长度)或者数字范围(例如3,12 表示长度从3到12的范围)
between 验证范围,定义的验证规则表示范围,可以使用字符串或者数组,例如1,31或者array(1,31)
notbetween 验证不在某个范围,定义的验证规则表示范围,可以使用字符串或者数组(3.1.2版本新增)
expire 验证是否在有效期,定义的验证规则表示时间范围,可以到时间,例如可以使用 2012-1-15,2013-1-15 表示当前提交有效期在2012-1-15到2013-1-15之间,也可以使用时间戳定义
ip_allow 验证IP是否允许,定义的验证规则表示允许的IP地址列表,用逗号分隔,例如201.12.2.5,201.12.2.6
ip_deny 验证IP是否禁止,定义的验证规则表示禁止的ip地址列表,用逗号分隔,例如201.12.2.5,201.12.2.6
unique 验证是否唯一,系统会根据字段目前的值查询数据库来判断是否存在相同的值,当表单数据中包含主键字段时unique不可用于判断主键字段本身
验证时间(可选)
self::MODEL_INSERT或者1新增数据时候验证
self::MODEL_UPDATE或者2编辑数据时候验证
self::MODEL_BOTH或者3全部情况下验证(默认)

这里的验证时间需要注意,并非只有这三种情况,你可以根据业务需要增加其他的验证时间。

array(‘repassword‘,‘password‘,‘确认密码不正确‘,0,‘confirm‘),

这是一个用户注册表单中对确认密码repassword的检验,repassword是需要检验的字段,password是检验规则,即两次输入的密码不相符怎会返回错误信息,0表示字段存在就会验证,confirm表示判断repassword和password是否相等。

当用户使用如下的方法时

<span>	</span>$User = D("user");
<span>	</span>$User->create();

就会自动进行验证。如果验证后发现字段不符合,则通过

<span>	</span>$User->getError();

来获取错误信息。

当然我们也可以自定义验证时间

<span>	</span>array('password','checkPwd','密码错误!',1,'function',4),

调用方法为

<span>	</span>$User = D("User"); // 实例化User对象
<span>	</span>if (!$User->create($_POST,4)){ // 登录验证数据
<span>		</span>// 验证没有通过 输出错误提示信息
<span>		</span>exit($User->getError());
<span>	</span>}else{
<span>		</span>// 验证通过 执行登录操作
<span>	</span>}

那么将会在此处使用设置了验证时间为4的规则

2.动态验证

动态验证中使用的规则格式与静态验证的相同

<span>	</span>$rules = array(
<span>		</span>array('verify','require','验证码必须!'), //默认情况下用正则进行验证
<span>		</span>array('name','','帐号名称已经存在!',0,'unique',1), // 在新增的时候验证name字段是否唯一
<span>		</span>array('value',array(1,2,3),'值的范围不正确!',2,'in'), // 当值不为空的时候判断是否在一个范围内
<span>		</span>array('repassword','password','确认密码不正确',0,'confirm'), // 验证确认密码是否和密码一致
<span>		</span>array('password','checkPwd','密码格式不正确',0,'function'), // 自定义函数验证密码格式
<span>	</span>);

<span>	</span>$User = M("User"); // 实例化User对象
<span>	</span>if (!$User->validate($rules)->create()){
<span>	</span>// 如果创建失败 表示验证没有通过 输出错误提示信息
<span>		</span>exit($User->getError());
<span>	</span>}else{
<span>		</span>// 验证通过 可以进行其他数据操作
<span>	</span>}

使用较为灵活,通常用M方法实例化模型类即可,不依赖于类的具体实现。

时间: 2024-08-29 16:24:18

Yii2.0模型层数据验证和thinkPHP3.2框架模型层数据验证对比的相关文章

YII2.0模型中的 rules的使用一

根据官方文档来说,http://www.yiichina.com/doc/guide/2.0/input-validation#standalone-validators    需要对模型中定义规则的 rules方法指定使用范围,否者的话每一次调用保存都会调用这个方法 官方文档解释: 对于每个规则,你至少需要指定该规则适用于哪些特性,以及本规则的类型是什么.你可以指定以下的规则类型之一: 核心验证器的昵称,比如 required.in.date,等等.请参考核心验证器章节查看完整的核心验证器列表

Yii2.0中(Hash is invalid error)验证错误

老项目数据迁移到Yii2.0后,密码仍使用md5加密.但是通过yii2.0的验证类的validatePassword($password)函数验证始终返回false: public function validatePassword($password){if(is_null($this->password)) return false;return Yii::$app->getSecurity()->validatePassword($this->salt . $password

yii2.0权限控制 ACF权限--登录验证

ACF是一种通过yii\filters\AccessControl类来实现的简单授权 一般在控制器中我们调用如下:打开backend\controller\SiteController.php 我们看到这样一段代码 public function behaviors(){return ['access' => ['class' => AccessControl::className(),'rules' => [['actions' => ['login', 'error'],'al

yii2.0 图片上传(摘录)

文章来源:http://blog.sina.com.cn/s/blog_88a65c1b0101izmn.html 下面小伙就带领大学学习一下 Yii2.0 的图片上传类的使用,还是老样子,如果代码样式混乱,我会附上截图供大家学习. 1.UserController.php 很重要的一步,那就是 use yii\web\UploadedFile; public function actionUpload(){ $model = new User(); user 为用户表model: if ($m

Yii2.0开发初学者必看

基础总结 1.修改默认控制器/方法 yii默认是site控制器,可以在web.php中设置$config中的'defaultRoute'='xxxx';使用自定义默认的控制器.也可以改写Yii::$app->defaultRoute属性. yii的默认方法是index,可以在vender/yiisoft/yii2/base/Controller.php 中进行初始设置,也可以在控制器中改写defaltAction='action'. 2.添加独立模块 yii可以在modules文件夹中添加自定义

yii2.0表单自带验证码

Yii2.0的自带的验证依赖于GD2或者ImageMagick扩展. 使用步骤如下: 第一步,控制器: 在任意controller里面重写方法 代码折叠,点击查看 <?php namespace frontend\controllers; use Yii; use app\models\login; use app\models\search\UserSearch; use yii\web\Controller; use yii\web\NotFoundHttpException; use yi

Yii2.0中文开发向导——高级应用程序模板

高级应用程序模板这个模板用在大型的团队开发项目中,而且后台从前台独立分离出来以便于部署在多个服务器中.由于YIi2.0的一些新的特性,这个程序模板的功能要更深一点.提供了基本的数据库的支持,注册.密码找回等功能.安装可以通过Composer来安装如果没有安装Composer,先安装 curl -s http://getcomposer.org/installer | php 然后用如下命令来获取 php composer.phar create-project --prefer-dist --s

Yii2.0 实现RESTful风格的简单API

一.创建数据库 首先,在mysql中创建一个名为yii2basic的数据库,并创建一张名为player的表. 二.配置 1.app/config/db.php <?php return [ 'class' => 'yii\db\Connection', 'dsn' => 'mysql:host=localhost;dbname=yii2basic', 'username' => 'root', 'password' => '', 'charset' => 'utf8',

yii2.0数据库查询修改等方法

yii2.0学习有一段时间了,给大家分享一下一些简单的查询等如何操作. 查询:(这里最前面的Test是引用的模型名) Test::find()->all();    此方法返回所有数据: 这些查询出来是对象形式,但是一般转换成数组格式: Test::find()->asArray()->all();     加上asArray()就取得数组形式的数据了,下面的自行添加. Test::findOne($id);   此方法返回 主键 id=1  的一条数据(举个例子): 条件查询:wher