ホームページ  >  記事  >  バックエンド開発  >  Yii2フレームワークのデータ検証運用例を詳しく解説

Yii2フレームワークのデータ検証運用例を詳しく解説

不言
不言オリジナル
2018-05-03 15:29:521841ブラウズ

この記事では、主に Yii2 フレームワークのデータ検証操作を紹介し、Yii フレームワークの一般的なデータ検証操作の原理、実装方法、および関連する操作テクニックをサンプルの形式で詳細に分析します。

この記事では、Yii2 フレームワークのデータを例とともに説明します。参考のために皆さんと共有してください。詳細は次のとおりです:

1. シナリオ

どのような状況でシナリオを使用する必要がありますか?モデルをさまざまなシナリオで使用する必要がある場合、さまざまなシナリオで必要なデータ テーブル フィールドとデータ検証ルールが異なる場合は、さまざまな使用シナリオを区別するために複数のシナリオを定義する必要があります。たとえば、ユーザーは登録時に電子メールを入力する必要がありますが、ログイン時には入力する必要はありません。この場合、それらを区別するために 2 つの異なるシナリオを定義する必要があります。

デフォルトでは、モデルシナリオは、rules() メソッドによって宣言された検証ルールで使用されるシナリオによって決定されます。これは、scenarios() メソッドをオーバーライドすることによって変更することもできます。 > メソッドで、モデルのすべてのシーンを具体的に定義します。例:

rules()方法申明的验证规则中使用到的场景决定的,也可以通过覆盖scenarios()方法来更具体地定义模型的所有场景,例如:

public function scenarios() {
    return [
      'signup' => ['username', 'email', 'password', 'conpassword', 'verifyCode', 'reg_time', 'log_time'],
      'login' => ['username', 'password', 'verifyCode', 'rememberMe', 'log_time']
    ];
}

其中键为场景名称,值为该场景下使用的模型属性(称为活动属性)。

指定模型场景有以下两种方法:

方法一:

$model = new User();
$model->scenario = 'signup';

方法二:

$model = new User(['scenario' => 'signup']);

可以通过指定验证规则中的'on'属性来申明一条验证规则适用的场景:

['email', 'required', 'on' => 'signup']

场景主要用于模型属性块赋值和数据验证。调用模型类的load()方法进行块赋值的时候,只有当前场景对应使用的属性会被赋值,调用模型类的validate()方法进行数据验证的时候,只有当前场景属性相关的且适用于当前场景的验证规则会被执行。

二、验证规则

Yii模型类通过实现rules()方法申明使用的所有验证规则,示例:

public function rules() {
    return [
      [['username', 'password'], 'required'],
      ['email', 'email', 'on' => 'signup']
    ];
}

一条规则可适用于一个或多个场景,一条规则可用来验证一个或多个属性,一个属性可对应一条或多条验证规则。如果没有指定'on'属性,验证规则会在所有场景下使用。

所有的验证规则都可以通过设置'message'属性来自定义错误信息,而且在错误信息内容中可以通过{attribute}来引用当前属性标签名称(属性标签名称需要在模型的attributeLabels()方法设置),通过{value}来引用当前属性的输入值,例如:

['username', 'unique', 'on' => 'register', 'message' => '{attribute}"{value}"已被占用!', 'on' => 'signup']//注册时用户名唯一

yii验证的使用方式有以下三种:

1. 客户端验证:

Yii默认开启客户端验证,可以通过设置enableClientValidation参数为true开启,开启之后ActiveForm会读取模型中申明的验证规则生成相应的Javascript验证代码。enableClientValidation参数设置的方式有三种:

(1)在视图文件ActiveForm中对整个form进行设置:

<?php
$form = ActiveForm::begin([
  &#39;enableClientValidation&#39; =>true
]);
?>

(2)在视图文件ActiveField中对单个field进行设置:

复制代码 代码如下:

<?= $form->field($model, &#39;username&#39;, [&#39;enableClientValidation&#39;=>false])->label(&#39;用户名&#39;) ?>

(3)在AR类的rules()函数中设置:
['username', 'yiivalidatorsStringValidator', 'min' => 3, 'max' => 30, 'enableClientValidation' => true, 'on' => 'register']

优先级:(2)>(1)>(3)

2. 服务器端验证:

(1)validate()

模型validate()方法会根据rules()方法中定义的验证规则对所有数据进行验证,验证通过返回true,否则将错误保存在yiibaseModel::errors属性中并返回false。

(2)save()

模型save()方法中默认调用validate()

<?php
$form = ActiveForm::begin([
  &#39;enableAjaxValidation&#39; =>true
]);
?>

ここで、キーはシーン名、値はシーンで使用されるモデル属性 (アクティビティ属性と呼ばれます) です。

モデルシーンを指定するには 2 つの方法があります:

方法 1:

<?= $form->field($model, &#39;username&#39;, [&#39;enableAjaxValidation&#39;=>false])->label(&#39;用户名&#39;) ?>


方法 2:

🎜🎜🎜
if(Yii::$app->request->isAjax) {
    $res = \yii\bootstrap\ActiveForm::validate($model);
    Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
    return $res;
}
🎜🎜🎜 は、検証ルール 検証ルールが適用されるシナリオ: 🎜🎜🎜
[&#39;state&#39;, &#39;required&#39;, &#39;when&#39; => function($model) {//只在country属性值为&#39;USA&#39;的时候state属性值才不能为空
     return $model->country==&#39;USA&#39;;
}]
🎜🎜🎜 このシナリオは、主にモデル属性ブロックの割り当てとデータ検証に使用されます。ブロック割り当てのためにモデル クラスの load() メソッドを呼び出すと、現在のシーンに対応する属性のみが割り当てられます。モデルの validate() メソッドを呼び出します。データ検証用のクラスを使用すると、現在のシーン属性に関連し、現在のシーンに適用される検証ルールのみが実行されます。 🎜🎜🎜🎜2. 検証ルール🎜🎜🎜🎜 Yii モデルクラスは、 rules() メソッドの実装によって使用されるすべての検証ルールを宣言します。 例: 🎜🎜🎜
[&#39;conpassword&#39;, function($attribute, $params) {
     if($this->$attribute != $this->newpassword) {
        $this->addError($attribute, &#39;确认密码和新密码不一致!&#39;);
    }
}]。
🎜🎜🎜 ルールは 1 つ以上のシナリオに適用できます。 1 つのルール 1 つ以上の属性を検証するために使用でき、1 つの属性は 1 つ以上の検証ルールに対応できます。 「on」属性が指定されていない場合、検証ルールはすべてのシナリオで使用されます。 🎜🎜すべての検証ルールは、「message」属性を設定することでエラー メッセージをカスタマイズでき、現在の属性ラベル名は、エラー メッセージの内容の {attribute} を通じて参照できます (属性ラベル名は、attributeLabels() で設定する必要があります)モデルのメソッド) では、{value} を通じて現在の属性の入力値を参照します。例: 🎜🎜['username', 'unique', 'on' => ; 'register', 'message' => '{attribute}"{value}" はすでに占有されています。 ', 'on' => 'signup']//yii 認証を使用するには 3 つの方法があります: 🎜🎜🎜Yii はデフォルトでクライアント認証をオンにします。これを有効にするには、enableClientValidation パラメーターを true に設定すると、ActiveForm はモデルで宣言された検証ルールを読み取り、対応する JavaScript 検証コードを生成します。 EnableClientValidation パラメータを設定するには 3 つの方法があります: 🎜🎜 (1) ビュー ファイルにフォーム全体を設定します。 ActiveForm: 🎜🎜🎜
namespace app\components;
use yii\validators\Validator;
class ConpasswordValidator extends Validator {
     public function init() {
         parent::init();
         $this->message = &#39;确认密码和密码不一致!&#39;;
     }
     //服务器端验证
     public function validateAttribute($model, $attribute) {
         if($model->conpassword !== $model->password) {
              $model->addError($attribute, $this->message);
         }
     }
     //客户端验证
     public function clientValidateAttribute($model, $attribute, $view) {
         $conpassword = json_encode($model->conpassword);
         $message = json_encode($this->message, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
     return <<<JS
if(value != $conpassword) {
     message.push($message);
}
JS;
         return false;
     }
}
🎜🎜🎜 (2) ビュー ファイルに単一のフィールドを設定します。 ActiveField: 🎜🎜

コードをコピーします🎜 コードは次のとおりです: 🎜rrreee🎜 (3) AR クラスの rules() 関数に設定します: 🎜['username', 'yiivalidatorsStringValidator', 'min' => 'max' => 'enableClientValidation' => 'on' => ]🎜🎜🎜優先度: (2)>(1)>(3)🎜🎜🎜2. サーバー側の検証:🎜🎜🎜(1) validate()🎜🎜モデル validate() メソッドはルールに基づきます。() メソッドで定義された検証ルールはすべてのデータを検証し、検証に合格した場合は true を返します。そうでない場合、エラーは <span style="color: #0000ff">yiibaseModel に保存されます。 ::errors🎜 属性を指定すると false が返されます。 🎜🎜(2) save()🎜🎜 モデルの <code>save() メソッドは、データ検証のためにデフォルトで validate() メソッドを呼び出します。検証に合格すると、データベース操作が実行されます。直接実行され、 true が返されます。それ以外の場合、データベース操作は実行されず、 false が返され、エラー情報が yiibaseModel::errors 属性に保存されます。 validate() が明示的に呼び出された場合は、パラメータ save(false) を渡すことで、save() メソッドでデータを繰り返し検証することを避けることができます。 🎜🎜🎜3. Ajax 検証: 🎜🎜🎜Yii はデフォルトで Ajax 検証をオフにし、enableAjaxValidation パラメーターを true に設定することでオンにできます。 🎜🎜クライアント設定 (2 つの方法): 🎜🎜 (1) ビュー ファイルにフォーム全体を設定する ActiveForm: 🎜🎜🎜rrreee🎜🎜🎜 (2) ビュー ファイルに単一フィールドを設定する ActiveField: 🎜🎜

复制代码 代码如下:

<?= $form->field($model, &#39;username&#39;, [&#39;enableAjaxValidation&#39;=>false])->label(&#39;用户名&#39;) ?>

优先级:(2)>(1)

服务器端处理:

if(Yii::$app->request->isAjax) {
    $res = \yii\bootstrap\ActiveForm::validate($model);
    Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
    return $res;
}

注:有些验证规则无法使用客户端验证,如:unique、exist等。

三、yii核心验证器

Yii提供了一些核心验证器,可以直接使用,申明格式如下:

['属性名', '验证器名称/类名', ...(一些额外参数设置)]

了解并使用yii的核心验证器会让开发变得简单许多。下面简单对yii核心验证器进行分类介绍。

1. 不进行数据验证的验证器

(1)safe:而是把一个属性标记为安全属性。

['desc', 'safe']

(2)default:给值为空的属性设置默认值。

['add_time', 'default', 'value' => time()]

(3)trim:去除输入值首尾两侧多余空格。

['username', 'trim']

(4)filter:滤镜,对数据进行格式化或一些其他处理后返回。

['phone', 'filter', 'filter' => function($value) {
         ....return $value;
}]

filter: 用于定义滤镜的php回调函数,可以为全局函数名,匿名函数或其他。
skipOnArray:是否在输入为数组时跳过滤镜,默认为false。如果滤镜不能处理数组输入,应该设置为true。

2. 数据类型验证器

(1)boolean:布尔型。

['del', 'boolean', 'trueValue' => true, 'falseValue' => false, 'strict' => true]

trueValue:代表真的值,默认为1。
falseValue:代表假的值,默认为0。
strict:是否要求输入数据必须严格匹配trueValue或falseValue。默认为false。

(2)number:数字。

['salary', 'number']

(3)double:双精度浮点型,等效于number验证器。

['salary','double', 'max' => 99.99, 'min' => 0]

(4)integer:整数。

['age', 'integer']

注:number、double、integer验证器都可以设置min、max参数来限制数字的最大、最小值(含界点)。

(5)string:字符串。

['username', 'string', 'length' => [3, 30]]

length:指定输入字符串的长度限制。
min:字符串最小长度。
max:字符串最大长度。
encoding:字符串的编码方式,不设置则使用应用自身的charset属性值。默认为utf-8。

3. 数据格式验证器

(1)date:日期。

['time', 'date', 'format' => 'php:Y:m:d', 'timestampAttribute' => 'startTime']

format:时间格式,默认为“y-m-d”。
timestampAttribute:将时间转化为时间戳并赋值给某个属性。

(2)email:验证是否符合邮箱地址格式。

['emailAddr', 'email']

(3)ip:验证是否为有效IP地址。

['ip_address', 'ip']

(4)url:网址。

['website', 'url', 'defaultScheme' => 'http']

validSchemes:用于指定哪些URI方案会被视为有效,默认为['http', 'https']。
defaultScheme:若输入值没有对应的方案前缀,会使用的默认URI方案前缀。

(5)match:输入值是否满足某个正则表达式。

['username', 'match', 'pattern' => '/^[a-z]\w*$/i']

pattern:正则表达式。
not:是否对验证结果取反。

4. 数据值验证器

(1)required:必填。

[['username', 'password'], 'required']

requiredValue:所期望的值,若没设置则输入不能为空。
strict:检查输入值时是否检查类型。

(2)captcha:验证码。

['verifyCode', 'captcha', 'caseSensitive' => true, 'captchaAction' => 'site/captcha', 'skipOnEmpty' => false]

caseSensitive:是否大小写敏感,默认为false。
captchaAction:指向用于渲染验证码图片的captcha方法的路由,默认为'site/captcha'。
skipOnEmpty:输入为空时是否跳过验证,默认为false。

(3)compare:比较。

['password', 'compare', 'compareAttribute' => 'conpassword', 'operator' => '==']

compareAttribute:与指定属性值比较的属性名称。
compareValue:与某个常量值比较。
operator:比较操作符。

其中compareAttribute默认在验证属性后面加后缀“_repeat”作为另一个比较属性的名称,operator默认为“==”,即:['password', 'compare']规则表示验证password与password_repeat的值是否相等。

(4)each:验证数组。

['ids', 'each', 'rule' => ['integer']]

(验证数组ids中的每个元素是否都是int类型数据)
rule:定义验证每一个数组元素的验证规则。
allowMessageFromRule:是否使用rule中指定的多个验证规则报错信息,默认为true,若设置为false,则使用“message”参数值作为错误信息。

注:若输入值不是数组则会报错

(5)exist:存在性。

['cid', 'exist', 'targetClass' => 'app\models\Category', 'targetAttribute' => 'id']

(cid的值是否在AR类对应的id属性中存在,使用场景:当前AR模型关联的数据表的cid字段和Category模型关联的数据表的id字段相关联,所以使用该验证规则验证cid字段的值能否在关联的另一个数据表中找到对应记录)
targetClass:用于查找输入值的目标AR类。
targetAttribute:用于查找输入值的目标属性名称。
filter:检查属性值存在性需要进行数据库查询,该参数设置查询的过滤条件。可以设置为查询条件的字符串或数组,或者function($query)匿名函数。
allowArray:是否允许输入值为数组,默认为false。若设置为true,则数组的每个元素都必须在目标字段中存在。若把targetAttribute设置为多元素数组来验证被测值在多字段中的存在性时,该属性不能设置为true。

(6)unique:唯一性。

['email', 'unique', 'targetClass' => 'app\models\User', 'message' => '{attribute}"{value}"已被注册!', 'on' => 'signup']
除了没有allowArray属性,其他属性都和exist验证器一样。

(7)in:范围。

['sex', 'in', 'range' => [0, 1, 2]]

range:范围值列表。
strict:是否使用严格模式(类型与值都要相同)。
not:是否对验证的结果取反,默认为false。
allowArray:是否接受输入数组,默认为false。

5. 文件验证器

(1)file:文件。

['pcImg', 'file', 'extensions' => ['png', 'jpg', 'gif'], 'maxSize' => 1024*1024]

extensions:可接受上传的文件扩展名列表。
mimeTypes:可接受上传的MIME类型列表。
minSize:文件大小下限。
maxSize:文件大小上限。
maxFiles:上传文件个数上限,默认为1。设置为大于1时输入值必须为数组。
checkExtensionByMimeType:是否通过文件的MIME类型来判断文件扩展,默认为true。

(2)image:图片。

['mbImg', 'image' extensions => 'png, ipg', 'minWidth' => 100, 'minHeight' => 100]

该验证器继承自file验证器,并支持额外属性minWidth、maxWidth、minHeight、maxHeight来设置图片的最小、最大宽度和最小、最大高度。

四、其他验证器

1. 条件式验证:

[&#39;state&#39;, &#39;required&#39;, &#39;when&#39; => function($model) {//只在country属性值为&#39;USA&#39;的时候state属性值才不能为空
     return $model->country==&#39;USA&#39;;
}]

注:若需要支持客户端验证,则要配置'whenClient'属性。

1. 自定义验证器:

(1)行内验证器:一种以模型方法或匿名函数的形式定义的验证器。

示例:

[&#39;conpassword&#39;, function($attribute, $params) {
     if($this->$attribute != $this->newpassword) {
        $this->addError($attribute, &#39;确认密码和新密码不一致!&#39;);
    }
}]。

(当然这里也可以使用yii核心验证器'compare'来实现)

注:行内验证器不支持客户端验证。

(2)独立验证器:

独立验证器是继承自yii\validators\Validator或其子类的类,可以通过重写validateAttribute()方法来实现验证规则,若验证失败,可以调用yii\base\Model::addError()方法来保存错误信息到模型内。

独立验证器示例:

namespace app\components;
use yii\validators\Validator;
class ConpasswordValidator extends Validator {
     public function init() {
         parent::init();
         $this->message = &#39;确认密码和密码不一致!&#39;;
     }
     //服务器端验证
     public function validateAttribute($model, $attribute) {
         if($model->conpassword !== $model->password) {
              $model->addError($attribute, $this->message);
         }
     }
     //客户端验证
     public function clientValidateAttribute($model, $attribute, $view) {
         $conpassword = json_encode($model->conpassword);
         $message = json_encode($this->message, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
     return <<<JS
if(value != $conpassword) {
     message.push($message);
}
JS;
         return false;
     }
}

模型中使用示例:

['conpassword', 'app\components\ConpasswordValidator']

最后要注意,验证规则申明的先后顺序对验证结果也是有影响的!

相关推荐:

Yii2框架类自动加载机制实例分析


以上がYii2フレームワークのデータ検証運用例を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。