模型是 MVC 模式中的一部分, 是代表业务数据、规则和逻辑的对象。

可通过继承 [[yii\base\Model]] 或它的子类定义模型类,基类[[yii\base\Model]]支持许多实用的特性:

  1. 属性: 代表可像普通类属性或数组一样被访问的业务数据;
  2. 属性标签: 指定属性显示出来的标签;
  3. 块赋值: 支持一步给许多属性赋值;
  4. 验证规则: 确保输入数据符合所申明的验证规则;
  5. 数据导出: 允许模型数据导出为自定义格式的数组。

属性:

所有 non-static public非静态公有 成员变量都是属性,如果是对应数据库的模型,我发现表的字段都是他的属性,而且是默认已经声明的,可以不用在手动声明。

属性标签:

这个主要是在视图中使用,而且为了统一修改,很方便的。通过方法 attributeLabels 返回一个数组或对象,我发现2.0以后的多少用对象代替了以前的数组方式。

 public function attributeLabels(){
return [
'name' => 'Your name',
'email' => 'Your email address',
'subject' => 'Subject',
'body' => 'Content',
];
}

场景:

一个模块可以在多个场景下使用,比如用户模型可以在注册和登录场景下使用,而且他们的验证规则甚至属性标签会有所不同,这就有了场景存在的必要性。可以通过 scenarios函数来实现。

 public function scenarios(){
$scenarios = parent::scenarios();
$scenarios['login'] = ['username', 'password'];
$scenarios['register'] = ['username', 'email', 'password'];
return $scenarios;
}

其中 $scenarios = parent::scenarios(); 可以保持默认场景的情况下,设置新场景的情况。

验证规则:

主要是针对表单的输入内容作出验证,比如用户名不能为空,email不能为空且必须是个邮箱的格式等等。可调用 [[yii\base\Model::validate()]] 来验证接收到的数据, 该方法使用[[yii\base\Model::rules()]]申明的验证规则来验证每个相关属性, 如果没有找到错误,会返回 true,否则它会将错误保存在 [[yii\base\Model::errors]] 属性中并返回false。

 $model = new \app\models\ContactForm;

 // 用户输入数据赋值到模型属性
$model->attributes = \Yii::$app->request->post('ContactForm'); if ($model->validate()) {
// 所有输入数据都有效 all inputs are valid
} else {
// 验证失败:$errors 是一个包含错误信息的数组
$errors = $model->errors;
}
 public function rules(){
return [
// 在"register" 场景下 username, email 和 password 必须有值
[['username', 'email', 'password'], 'required', 'on' => 'register'], // 在 "login" 场景下 username 和 password 必须有值
[['username', 'password'], 'required', 'on' => 'login'],
];
}

在rules方法中还可以标明这个规则是在哪个场景下使用的,如不是所有场景的话,就省去 'on'=>'',一行可以设置多个字段的规则也可以多行设置一个字段的规则,根据实际情况来做。

块赋值:

这个其实是个很好的东西,可以快速赋值表单传来的值,比如下面的赋值方式就把整个 ContactForm 表单的值赋值过来了。

$model = new \app\models\ContactForm;
$model->attributes = \Yii::$app->request->post('ContactForm');

安全属性:

块赋值只应用在模型当前[[yii\base\Model::scenario|scenario]]场景[[yii\base\Model::scenarios()]]方法 列出的称之为 安全属性 的属性上,例如,如果User模型申明以下场景, 当当前场景为login时候,只有username and password 可被块赋值,其他属性不会被赋值。

public function scenarios(){
return [
'login' => ['username', 'password'],
'register' => ['username', 'email', 'password'],
];
}

由于默认[[yii\base\Model::scenarios()]]的实现会返回[[yii\base\Model::rules()]]所有属性和数据, 如果不覆盖这个方法,表示所有只要出现在活动验证规则中的属性都是安全的。

为此,提供一个特别的别名为 safe 的验证器来申明哪些属性是安全的不需要被验证, 如下示例的规则申明 title 和 description 都为安全属性。

public function rules(){
return [
[['title', 'description'], 'safe'],
];
}

非安全属性:

相对于安全属性就有非安全属性,在某些情况下,你可能想验证一个属性但不想让他是安全的,可在scenarios()方法中属性名加一个惊叹号 !。例如像如下的secret属性。他的赋值就要单独的显式赋值。

public function scenarios(){
return [
'login' => ['username', 'password', '!secret'],
];
} $model->secret = $secret;

数据导出:

其实简单说就是获取数据表的一个结果集,最简单的就是使用 attributes方法。

$post = \app\models\Post::findOne(100);
$array = $post->attributes;

更灵活和强大的将模型转换为数组的方式是使用 [[yii\base\Model::toArray()]] 方法, 它的行为默认和 [[yii\base\Model::attributes]] 相同, 但是它允许你选择哪些称之为字段的数据项放入到结果数组中并同时被格式化。 实际上,它是导出模型到 RESTful 网页服务开发的默认方法。

字段:

字段是模型通过调用[[yii\base\Model::toArray()]]生成的数组的单元名。默认情况下字段和属性是对应的。但是你可以通过覆盖 [[yii\base\Model::fields()|fields()]] 和/或 [[yii\base\Model::extraFields()|extraFields()]] 方法来改变这种行为, 两个方法都返回一个字段定义列表,fields() 方法定义的字段是默认字段,表示toArray()方法默认会返回这些字段。 extraFields()方法定义额外可用字段,通过toArray()方法指定$expand参数来返回这些额外可用字段。 例如如下代码会返回fields()方法定义的所有字段和extraFields()方法定义的prettyName and fullAddress字段。

$array = $model->toArray([], ['prettyName', 'fullAddress']);

可通过覆盖 fields() 来增加、删除、重命名和重定义字段,fields() 方法返回值应为数组, 数组的键为字段名,数组的值为对应的可为属性名或匿名函数返回的字段定义对应的值。 特使情况下,如果字段名和属性定义名相同,可以省略数组键,例如:

// 明确列出每个字段,特别用于你想确保数据表或模型属性改变不会导致你的字段改变(保证后端的API兼容).
public function fields(){
return [
// 字段名和属性名相同
'id', // 字段名为 "email",对应属性名为 "email_address"
'email' => 'email_address', // 字段名为 "name", 值通过PHP代码返回
'name' => function () {
return $this->first_name . ' ' . $this->last_name;
},
];
} // 过滤掉一些字段,特别用于你想继承父类实现并不想用一些敏感字段
public function fields(){
$fields = parent::fields(); // 去掉一些包含敏感信息的字段
unset($fields['auth_key'], $fields['password_hash'], $fields['password_reset_token']); return $fields;
}

除了上面说的模型自身的东西外,在使用的时候也应注意一些事情:

  1. 不应直接访问请求,session和其他环境数据,这些数据应该由控制器传入到模型;
  2. 应避免嵌入HTML或其他展示代码,这些代码最好在 视图中处理;
  3. 单个模型中避免太多的 场景.

在开发大型复杂系统时应经常考虑最后一条建议, 在这些系统中,模型会很大并在很多地方使用,因此会包含需要规则集和业务逻辑, 最后维护这些模型代码成为一个噩梦,因为一个简单修改会影响好多地方, 为确保模型好维护,最好使用以下策略:

  • 定义可被多个 应用主体 或 模块 共享的模型基类集合。 这些模型类应包含通用的最小规则集合和逻辑。
  • 在每个使用模型的 应用主体 或 模块中, 通过继承对应的模型基类来定义具体的模型类,具体模型类包含应用主体或模块指定的规则和逻辑。

例如,在高级应用模板,你可以定义一个模型基类common\models\Post, 然后在前台应用中,定义并使用一个继承common\models\Post的具体模型类frontend\models\Post, 在后台应用中可以类似地定义backend\models\Post。 通过这种策略,你清楚frontend\models\Post只对应前台应用,如果你修改它,就无需担忧修改会影响后台应用。

Yii框架2.0的模型的更多相关文章

  1. Yii框架2.0的安装过程

    Yii框架是个不错的php开发框架,大型项目上都可以使用.和大多框架一样他也是开源,而且采用了mvc结构的. Yii1.*,直接下载然后用脚步可以创建自己的项目了,最近看了下Yii2.0版本的,他推荐 ...

  2. Yii框架2.0的Gii

    Yii框架的Gii在我看来算是个快速创建器,当然对于学习来说意义不大,但对于已经懂得他的原理并用他开发的话,就是个快速开发的好工具. 他能快速的创建控制器,模块,crup,插件,Module. 打开g ...

  3. Yii框架2.0的 验证码

    最近看了一个Yii的教程视频,是按1.1的版本讲的,我想用Yii2.0的框架也参考他的学习开发下,结果发现好多不一样的,现在就说说验证码的事 首先加入一个actions 做验证码图片的显示,实际事调用 ...

  4. Yii框架2.0的控制器

    控制器是继承[[yii\base\Controller]]类的对象,负责处理请求和生成响应. 具体来说,控制器从应用主体接管控制后会分析请求数据并传送到模型, 传送模型结果到视图,最后生成输出响应信息 ...

  5. Yii框架2.0的视图和widgets表单的使用

    2.0的控制器的创建和action方法的添加和1.0的基本是一样的.但我发现他的widgets 的ActiveForm和1.1版本有些不一样的地方. 对于视图基本也是一样的,有render 和 ren ...

  6. Yii框架2.0的模块

    模块是个独立的软件单元,也是又控制器,视图,模型组成的,也可以有自己的布局.但他必须属于某个应用下,不能独立存在. 其中模块的控制器,视图和应用的控制器和视图使用基本相同,不作赘述,下面说说模块的使用 ...

  7. Yii框架2.0的小部件

    小部件是视图里的可重用单元. 小部件是在视图中使用的,但是可能需要使用控制器传给他的模型,比如在渲染表单的时候.比如一般的时间拾取器就可以直接砸视图里加入如下代码就可以: <?php use y ...

  8. Yii框架2.0 数据库操作初接触

    Yii2.0和Yii1.1版本的变动还是挺多的,我发现配置文件有许多不同,Yii1.1版本里有个main.php 好多信息是在这里配置的,比如默认控制器,数据库连接信息:Yii的数据库配置被单独拿出来 ...

  9. Yii框架2.0的过滤器

    过滤器是 控制器 动作 执行之前或之后执行的对象. 例如访问控制过滤器可在动作执行之前来控制特殊终端用户是否有权限执行动作, 内容压缩过滤器可在动作执行之后发给终端用户之前压缩响应内容. 过滤器可包含 ...

随机推荐

  1. mybatis、ibatis 和spring集成

    mybatis是ibatis的升级版,spring也有自带mybatis的orm.所以,搭建ibatis的框架也会有多种方式(我这里mybatis是3.0的,ibatis是2.3的,spring是3. ...

  2. CSS学习笔记(9)--详解CSS中:nth-child的用法

    详解CSS中:nth-child的用法 前端的哥们想必都接触过css中一个神奇的玩意,可以轻松选取你想要的标签并给与修改添加样式,是不是很给力,它就是“:nth-child”. 下面我将用几个典型的实 ...

  3. Groovy学习()Groovy是啥?

    Groovy是啥? groovy是英文中的一个单词,有marvelous.wonderful和excellen的意思. groovy是轻量级的,动态的,面向对象的,并且运行在JVM上的. groovy ...

  4. yum whatprovides host 根据命令查找包

    [root@Cobbler ~]# yum whatprovides host Loaded plugins: fastestmirror Loading mirror speeds from cac ...

  5. 随机算法 - HNU 13348 Finding Lines

    Finding Lines Problem's Link: http://acm.hnu.cn/online/?action=problem&type=show&id=13348&am ...

  6. 判断gridView是否有数据

    我这里的gridView是采用空模板数据来显示的 当gridView的数据源为空的时候它们就会显示标题 有数据的显示它们就会显示下面的这种 你仔细观察会发现,当有数据的时候空标题的table没有了,解 ...

  7. 一个美国人对"智能制造"的思考!

    世界上制造业最强的国家仍然是美国!如今,国内工业4.0概念讨论日益喧嚣,中德合作如火如荼,但我们不能否认这个事实. “ 当下,美国似乎失去了世界第一制造大国的称号,而中国的企业也正面临产值下滑.利润下 ...

  8. 编译内核出现"mkimage" command not found - U-Boot images will not be built

    参考链接: http://spyker729.blogspot.com/2010/07/mkimage-command-not-found-u-boot-images.html 制作uImage的工具 ...

  9. Collection接口都是通过Iterator()(即迭代器)来对Set和List遍历

    以下介绍接口: List接口:(介绍其下的两个实现类:ArrayList和LinkedList) ArrayList和数组非常类似,其底层①也用数组组织数据,ArrayList是动态可变数组. ① 底 ...

  10. ThinkPHP项目笔记之RBAC(权限相关视频讲解篇

    感谢互联网,只要你愿意找,没有找不到的免费资源 网址:http://www.studyfox.cn/143.html