Yii2 中的自定义属性验证
Custom attribute validation in Yii2
我有模型表单 (SomeForm
) 和自定义验证函数:
use yii\base\Model;
class SomeForm extends Model
{
public $age;
public function custom_validation($attribute, $params){
if($this->age < 18){
$this->addError($attribute, 'Some error Text');
return true;
}
else{
return false;
}
}
public function rules(){
return [
['age', 'custom_validation']
];
}
}
我在 rules()
函数中使用了这个 custom_validation
但表单甚至提交了具有 age
属性的任何值。
表格如下:
age.php
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'age')->label("Age") ?>
<div class="form-group">
<?= Html::submitButton('Submit', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
和控制器:
use yii\web\Controller;
class SomeController extends Controller
{
//this controller is just for rendering
public function actionIndex(){
return $this->render('age');
}
public function actionSubmit(){
$model = new SomeForm();
if($model->load(Yii::$app->request->post()){
//do something here
}
}
}
您不需要 return 任何东西,只需将错误添加到属性中就足够了。
从版本 2.0.11
开始,您可以立即使用 yii\validators\InlineValidator::addError()
for adding errors instead of using $this
. That way the error message can be formatted using yii\i18n\I18N::format()
。
在错误消息中使用{attribute}
和{value}
来引用属性标签(无需手动获取)和相应的属性值:
我怀疑你的问题是你错过了 $formModel->validate()
因为在上面给出的模型中扩展了 yii\base\Model
而不是 \yii\db\ActiveRecord
并且你必须保存一些其他 ActiveRecord
模型并想在保存 ActiveRecord
模型之前验证此 FormModel
,您必须调用 $formModel->validate()
来检查是否提供了有效输入并触发模型验证将 post 数组加载到模型后。
另一件需要注意的事情是,默认情况下,如果内联验证器的关联属性接收到空输入,或者如果它们已经未能通过某些验证规则,则不会应用内联验证器。如果您想确保始终应用规则,您可以在规则声明中将 skipOnEmpty
and/or skipOnError
属性配置为 false
。
您的模型应该如下所示您在模型定义中缺少 namespace
如果这不仅仅是故意的或由于示例代码。只需根据它所在的路径更新你的命名空间。
namespace frontend\models;
use yii\base\Model;
class SomeForm extends Model
{
public $age;
const AGE_LIMIT=18;
public function rules(){
return [
['age', 'custom_validation','skipOnEmpty' => false, 'skipOnError' => false]
];
}
public function custom_validation($attribute, $params,$validator){
if($this->$attribute< self::AGE_LIMIT){
$validator->addError($this, $attribute, 'The value "{value}" is not acceptable for {attribute}, should be greater than '.self::AGE_LIMIT.'.');
}
}
}
你的 controller/action
应该看起来像
public function actionTest()
{
//use appropriate namespace
$formModel = new \frontend\models\SomeForm();
$model= new \frontend\models\SomeActiveRecordModel();
if ($formModel->load(Yii::$app->request->post()) && $model->load(Yii::$app->request->post())) {
if ($formModel->validate()) {
// your code after validation to save other ActiveRecord model
if($model->save()){
Yii::$app->session->setFlash('success','Record added succesfully.')
}
}
}
return $this->render('test', ['model' => $model,'formModel'=>$formModel]);
}
视图文件中的输入字段 age
应使用 $formMoedl
对象
echo $form->field($formModel, 'age')->textInput();
我有模型表单 (SomeForm
) 和自定义验证函数:
use yii\base\Model;
class SomeForm extends Model
{
public $age;
public function custom_validation($attribute, $params){
if($this->age < 18){
$this->addError($attribute, 'Some error Text');
return true;
}
else{
return false;
}
}
public function rules(){
return [
['age', 'custom_validation']
];
}
}
我在 rules()
函数中使用了这个 custom_validation
但表单甚至提交了具有 age
属性的任何值。
表格如下:
age.php
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'age')->label("Age") ?>
<div class="form-group">
<?= Html::submitButton('Submit', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
和控制器:
use yii\web\Controller;
class SomeController extends Controller
{
//this controller is just for rendering
public function actionIndex(){
return $this->render('age');
}
public function actionSubmit(){
$model = new SomeForm();
if($model->load(Yii::$app->request->post()){
//do something here
}
}
}
您不需要 return 任何东西,只需将错误添加到属性中就足够了。
从版本 2.0.11
开始,您可以立即使用 yii\validators\InlineValidator::addError()
for adding errors instead of using $this
. That way the error message can be formatted using yii\i18n\I18N::format()
。
在错误消息中使用{attribute}
和{value}
来引用属性标签(无需手动获取)和相应的属性值:
我怀疑你的问题是你错过了 $formModel->validate()
因为在上面给出的模型中扩展了 yii\base\Model
而不是 \yii\db\ActiveRecord
并且你必须保存一些其他 ActiveRecord
模型并想在保存 ActiveRecord
模型之前验证此 FormModel
,您必须调用 $formModel->validate()
来检查是否提供了有效输入并触发模型验证将 post 数组加载到模型后。
另一件需要注意的事情是,默认情况下,如果内联验证器的关联属性接收到空输入,或者如果它们已经未能通过某些验证规则,则不会应用内联验证器。如果您想确保始终应用规则,您可以在规则声明中将 skipOnEmpty
and/or skipOnError
属性配置为 false
。
您的模型应该如下所示您在模型定义中缺少 namespace
如果这不仅仅是故意的或由于示例代码。只需根据它所在的路径更新你的命名空间。
namespace frontend\models;
use yii\base\Model;
class SomeForm extends Model
{
public $age;
const AGE_LIMIT=18;
public function rules(){
return [
['age', 'custom_validation','skipOnEmpty' => false, 'skipOnError' => false]
];
}
public function custom_validation($attribute, $params,$validator){
if($this->$attribute< self::AGE_LIMIT){
$validator->addError($this, $attribute, 'The value "{value}" is not acceptable for {attribute}, should be greater than '.self::AGE_LIMIT.'.');
}
}
}
你的 controller/action
应该看起来像
public function actionTest()
{
//use appropriate namespace
$formModel = new \frontend\models\SomeForm();
$model= new \frontend\models\SomeActiveRecordModel();
if ($formModel->load(Yii::$app->request->post()) && $model->load(Yii::$app->request->post())) {
if ($formModel->validate()) {
// your code after validation to save other ActiveRecord model
if($model->save()){
Yii::$app->session->setFlash('success','Record added succesfully.')
}
}
}
return $this->render('test', ['model' => $model,'formModel'=>$formModel]);
}
视图文件中的输入字段 age
应使用 $formMoedl
对象
echo $form->field($formModel, 'age')->textInput();