资讯专栏INFORMATION COLUMN

Yii2系列教程七:Behaviors And Validations

fasss / 2597人阅读

摘要:原文来自这一篇文章的开头就无需多言了,紧接着上一篇的内容和计划,这一篇我们来说说的和。,那既然这样,我们就来实现一下呗。所以我们首先需要将表中的几条数据删掉。下一节再详细讲讲吧,这一节写下来貌似要说的实在有点多。

  

原文来自: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" => "yiiehaviorsTimestampBehavior",
                "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 yiiehaviorsBlameableBehavior;
use yiidbActiveRecord;

这些工作都完成之后,我们就可以将我们原来在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来看看:

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

到这里,我们的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文件:

再生成CRUD文件:

然后打开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字段保留为空,那么这个字段就会默认取值为当天的日期。

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

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

下一节

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

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

Happy Hacking

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/21058.html

相关文章

  • Yii2系列教程六:集成编辑器

    摘要:而这些问题目前的最好解决方案就是集成一个编辑器,鉴于大家这里不是指程序员都是喜欢所见即所得,所以,这里我主要是演示怎么集成所见即所得的富文本编辑器。 原文来自: https://jellybool.com/post/programming-with-yii2-rich-text-input-with-redactor 首先,很惭愧的是,前几天都出去外面玩了,没有及时更新教程,...

    xiaochao 评论0 收藏0
  • Yii2.0 RESTful API 之速率限制

    摘要:之速率限制什么是速率限制权威指南翻译过来为限流,为防止滥用,你应该考虑对您的限流。如果在规定的时间内接收了一个用户大量的请求,将返回响应状态代码这意味着过多的请求。 Yii2.0 RESTful API 之速率限制 什么是速率限制? 权威指南翻译过来为限流,为防止滥用,你应该考虑对您的 API 限流。 例如,您可以限制每个用户 10 分钟内最多调用 API 100 次。 如果在规定的时...

    LeviDing 评论0 收藏0
  • Yii2系列教程五:简单的用户权限管理

    摘要:原文来自上一篇文章讲了用户的注册,验证和登录,这一篇文章按照约定来说说之中的用户和权限控制。探寻上面的一些列设置和代码更改,已经实现了一小部分的用户控制登录的用户才能发表。 原文来自: https://jellybool.com/post/programming-with-yii2-user-access-controls 上一篇文章讲了用户的注册,验证和登录,这一篇文章按照...

    livem 评论0 收藏0
  • 阿北的知识分享小程序中restful使用经验贴

    摘要:大家知道我最近在给阿北的知识分享微信小程序改版,使用的是中的功能,接下来把遇到的一些问题及小技巧分享一下。小结以上就是目前为止在使用的开发小程序时候使用的一些知识和技巧,希望对你有用,以后如果有再分享哈。 大家知道我最近在给阿北的知识分享微信小程序改版,使用的是yii2中的restful功能,接下来把遇到的一些问题及小技巧分享一下。 先安利一下小程序码 链接 开始分享。 URL要重写 ...

    Meils 评论0 收藏0
  • Yii2配置Nginx反向代理缓存提高并发支持

    摘要:首先,在的主配置文件里先设置好与缓存相关的配置这里需要先手工建立与缓存相应的目录,并且把它设置为可读写。另外如果升级成,对不用缓存的部分性能也会有提升,这就不在本文讨论的范围之内了。 现有一个系统是用Yii2框架开发的,Web服务器采用Nginx+php-fpm,由于没有使用Nginx的反向代理缓存技术,用Apache的ab一压就死掉了,QPS只能达到7或者8的水平,像这样是无法支持高...

    callmewhy 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<