转载

Yii2系列教程七:Behaviors And Validations

原文来自: https://jellybool.com/post/programming-with-yii2-behaviors-and-validat...

这一篇文章的开头就无需多言了,紧接着上一篇的内容和计划,这一篇我们来说说Yii2的Behavior和Validations。

Behavior

首先我们来说说Behavior,在Yii2中Behavior主要是可以用于一些常用的Model字段当中,对其进行自动化操作,比如自动添加一些时间戳字段等,这样我们就不用在每一个需要保存记录的地方分别写生成时间戳的代码了,比如前面我们在 Yii2系列教程五:简单的用户权限管理 中的 controllers/StatusController.phpactionCreate 方法实现的

    $model->created_by = Yii::$app->user->getId();//add this line     $model->created_at = time();     $model->updated_at = time();  

这些其实我们都是可以直接放在 Status 这个Model的 behaviors() 方法当中自动完成的。

OK,那既然这样,我们就来实现一下呗。

首先我们需要来喂我们的status表增加一个 updated_by 字段,用来记录是哪个用户对一条状态进行了更新:

./yii migrate/create extend_status_table_for_updated_by   

执行完上面的命令之后,来到相对应的 migration 文件中,为其 up()down() 方法增加下面的代码:


public function up() { $this->addColumn('{{%status}}','updated_by',Schema::TYPE_INTEGER.' NOT NULL'); $this->addForeignKey('fk_status_updated_by', '{{%status}}', 'updated_by', '{{%user}}', 'id', 'CASCADE', 'CASCADE'); } public function down() { $this->dropForeignKey('fk_status_updated_by','{{%status}}'); $this->dropColumn('{{%status}}','updated_by'); }

这个时候先不急着运行 ./yii migrate/up ,因为这时候你运行 ./yii migrate/up 其实是会报错的,因为对于已创建的status来说,它 updated_by 字段会默认为0,但是这个值在 user 这张表中并不存在。所以我们首先需要将 status 表中的几条数据删掉。鉴于这只是一个演示的小应用,为了保险起见,我将 stutas 这张表删除了,并且将 migration 这张表的于下面类似的两条记录删掉,以达到Yii2的migration重新创建 stutas 表的目的:

m150804_035107_create_status_table m150806_034325_extend_status_table_for_created_by  

然后再执行 ./yii migrate/up

./yii migrate/up Yii Migration Tool (based on Yii v2.0.6) Total 3 new migrations to be applied:  m150804_035107_create_status_table  m150806_034325_extend_status_table_for_created_by  m150812_142736_extend_status_table_for_updated_by Apply the above migrations? (yes|no) [no]:yes *** applying m150804_035107_create_status_table  > create table {{%status}} ... done (time: 0.025s) *** applied m150804_035107_create_status_table (time: 0.033s) *** applying m150806_034325_extend_status_table_for_created_by  > add column created_by integer NOT NULL to table {{%status}} ... done (time: 0.036s)  > add foreign key fk_status_created_by: {{%status}} (created_by) references {{%user}} (id) ... done (time: 0.014s) *** applied m150806_034325_extend_status_table_for_created_by (time: 0.053s) *** applying m150812_142736_extend_status_table_for_updated_by  > add column updated_by integer NOT NULL to table {{%status}} ... done (time: 0.017s)  > add foreign key fk_status_updated_by: {{%status}} (updated_by) references {{%user}} (id) ... done (time: 0.017s) *** applied m150812_142736_extend_status_table_for_updated_by (time: 0.037s)  

数据表创建完成之后,我们需要在 Status 这个Model文件中增加我们的behaviors方法:

public function behaviors()  {   return [    [     'class' => BlameableBehavior::className(),     'createdByAttribute' => 'created_by',     'updatedByAttribute' => 'updated_by',    ],    'timestamp' => [     'class' => 'yii/behaviors/TimestampBehavior',     'attributes' => [      ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'],      ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'],     ],    ],   ];  }  

return 的数组当中,第一个就是使用Yii2的 BlameableBehavior 自动完成 created_byupdated_by 这两个字段,至于 timestamp 这个数组,就是使用Yii2的 TimestampBehavior 来自动完成created_at和 updated_at 字段,并且这会根据数据的 BEFORE_INSERTBEFORE_UPDATE 两种情况来自动完成添加。

需要注意的是,我们这时候需要在 Status 中引入下面两个类:

use yii/behaviors/BlameableBehavior; use yii/db/ActiveRecord;  

这些工作都完成之后,我们就可以将我们原来在 controllers/StatusController.phpactionCreate 方法的相关那几行注释掉了:

public function actionCreate()  {   $model = new Status();   if ($model->load(Yii::$app->request->post())) {      /* $model->created_by = Yii::$app->user->getId();    $model->created_at = time();    $model->updated_at = time();*/    if ($model->save()) {     return $this->redirect(['view', 'id' => $model->id]);    }   }   return $this->render('create', [    'model' => $model,   ]);  }  

注释掉之后,我们可以访问 http://localhost:8999/status/create 来创建一条新的 status 来看看:

Yii2系列教程七:Behaviors And Validations

点击创建按钮,你依然可以看到下面这个可爱的页面:

Yii2系列教程七:Behaviors And Validations

到这里,我们的Behavior在Yii2中就已经实现完毕了。下面来看看Validations

Validations

Yii2的Validation提供多种多样的验证机制,比如常见的email,图片,数字等,更多的验证机制和条件,你可以到这里查看文档:

http://www.yiiframework.com/doc-2.0/yii-validators-validator.html

这里我想说明的一点是,在Yii2之中,Validation通常都是通过 validate() 来实现的,那么这个`validate()`` 方法的背后其实是怎么样的呢?可以看看下面这个顺序:

1. 首先检测Model当中有没有`scenarios()`方法,如果该方法存在,则首先执行该方法里面对应的场景之下的验证规则  2. 再检测Model当中的`rules()`方法,然后执行验证规则  

为了演示方便,我们来创建一个新的Migrations:

./yii migrate/create create_sample_table  

然后还是想之前一样,来到相对应的migration文件当中,实现 up()down() 方法:

public function up()  {   $tableOptions = null;   if ($this->db->driverName === 'mysql') {    $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB';   }   $this->createTable('{{%sample}}', [    'id' => Schema::TYPE_PK,    'thought' => Schema::TYPE_STRING.' NOT NULL DEFAULT ""',    'goodness' => Schema::TYPE_SMALLINT . ' NOT NULL DEFAULT 0',    'rank' => Schema::TYPE_INTEGER . ' NOT NULL',    'censorship' => Schema::TYPE_STRING . ' NOT NULL',    'occurred' => Schema::TYPE_DATE . ' NOT NULL',   ], $tableOptions);  }  public function down()  {   $this->dropTable('{{%sample}}');  }  

然后执行之:

./yii migrate/up Yii Migration Tool (based on Yii v2.0.6) Total 1 new migration to be applied:  m150812_153139_create_sample_table Apply the above migration? (yes|no) [no]:yes *** applying m150812_153139_create_sample_table  > create table {{%sample}} ... done (time: 0.026s) *** applied m150812_153139_create_sample_table (time: 0.037s)  

使用Gii生成Model文件:

Yii2系列教程七:Behaviors And Validations

再生成CRUD文件:

Yii2系列教程七:Behaviors And Validations

Yii2系列教程七:Behaviors And Validations

然后打开 SampleController.php ,你就可以看到Yii2为我们生成的 rules() 了:

 public function rules()  {   return [    [['goodness', 'rank'], 'integer'],    [['rank', 'censorship', 'occurred'], 'required'],    [['occurred'], 'safe'],    [['thought', 'censorship'], 'string', 'max' => 255]   ];  }  

Default Value验证

我门修改一下rules()方法里面的occurred字段的验证,给它设置一个默认值:

return [  [['goodness', 'rank'], 'integer'],  [['rank', 'censorship'], 'required'],  // Gii generate this  //[['occurred'], 'safe'],  ['occurred', 'default', 'value' => date('Y-m-d')],  [['thought', 'censorship'], 'string', 'max' => 255]         ];  

然后当我们创建一个新的Sample的时候,如果我们将 occurred 字段保留为空,那么这个字段就会默认取值为当天的日期。

Yii2系列教程七:Behaviors And Validations

Rank填入2,然后创建后是这样的:

Yii2系列教程七:Behaviors And Validations

至于另外的验证规则,你可以自己试着更改一下 rules() 方法里面的规则,然后进行相应的验证。

下一节

再详细讲讲Validations吧,这一节写下来貌似Validations要说的实在有点多。

Github源码: https://github.com/JellyBool/helloYii

Happy Hacking

正文到此结束
Loading...